Changeset: 559f57c2691f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=559f57c2691f
Modified Files:
        gdk/gdk_system.c
        gdk/gdk_system.h
        sql/backends/monet5/cquery.mal
        sql/backends/monet5/sql_cquery.c
        sql/backends/monet5/sql_cquery.h
        sql/backends/monet5/sql_timestamps.c
        sql/backends/monet5/sql_timestamps.h
Branch: trails
Log Message:

Delay of the continuous query beginning working


diffs (truncated from 386 to 300 lines):

diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c
--- a/gdk/gdk_system.c
+++ b/gdk/gdk_system.c
@@ -947,3 +947,55 @@ GDKms(void)
 {
        return (int) (GDKusec() / 1000);
 }
+
+lng
+GDKunix_timestamp_usec(void)
+{
+       /* Return the time in microseconds since an epoch. */
+#ifdef _MSC_VER
+       {
+               FILETIME ft;
+               lng tt;
+
+               GetSystemTimeAsFileTime(&ft);
+               tt = ft.dwHighDateTime;
+               tt <<= 32;
+               tt |= ft.dwLowDateTime;
+               tt /= 10;
+               tt -= 11644473600000000L;
+
+               return (lng) tt;
+       }
+#endif
+#ifdef HAVE_CLOCK_GETTIME
+       {
+               struct timespec ts;
+
+               if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
+                       return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
+       }
+#endif
+#ifdef HAVE_GETTIMEOFDAY
+       {
+               struct timeval tp;
+
+               gettimeofday(&tp, NULL);
+               return (lng) tp.tv_sec * 1000000 + (lng) tp.tv_usec;
+       }
+#else
+#ifdef HAVE_FTIME
+       {
+               struct timeb tb;
+
+               ftime(&tb);
+               return (lng) tb.time * 1000000 + (lng) tb.millitm * 1000;
+       }
+#endif
+#endif
+}
+
+int
+GDKunix_timestamp_msec(void)
+{
+       return (int) (GDKunix_timestamp_usec() / 1000);
+}
diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h
--- a/gdk/gdk_system.h
+++ b/gdk/gdk_system.h
@@ -356,4 +356,7 @@ gdk_export int MT_check_nr_cores(void);
 gdk_export lng GDKusec(void);
 gdk_export int GDKms(void);
 
+gdk_export lng GDKunix_timestamp_usec(void);
+gdk_export int GDKunix_timestamp_msec(void);
+
 #endif /*_GDK_SYSTEM_H_*/
diff --git a/sql/backends/monet5/cquery.mal b/sql/backends/monet5/cquery.mal
--- a/sql/backends/monet5/cquery.mal
+++ b/sql/backends/monet5/cquery.mal
@@ -25,9 +25,6 @@ the MAL block to determine the input/out
 pattern resume(mod:str, fcn:str)
 address CQresume
 comment "Activate a specific continuous query with no changes";
-pattern resumenoalter(mod:str, fcn:str)
-address CQresumeNoAlter
-comment "Activate a specific continuous query with changes to the cycles and 
heartbeat values";
 
 pattern resume()
 address CQresumeAll
@@ -56,15 +53,25 @@ comment "Sleep for some time";
 pattern cycles(mod:str, fcn:str,cnt:int)
 address CQcycles
 comment "Limit number of petrinet steps";
+
 pattern cycles(cnt:int)
 address CQcycles
 comment "Limit number of petrinet steps";
 
+pattern beginat(mod:str, fcn:str,beginat:lng)
+address CQbeginAt
+comment "Delay beginning of a continuous query, where beginat is an UNIX 
timestamp with microsecond precision";
+
+pattern beginat(beginat:lng)
+address CQbeginAt
+comment "Delay beginning of all continuous queries, where beginat is an UNIX 
timestamp with microsecond precision";
+
 # scheduler heart beat for each CQ
-pattern heartbeat(mod:str, fcn:str,cnt:int)
+pattern heartbeat(mod:str, fcn:str,cnt:lng)
 address CQheartbeat
 comment "Awake the query after cnt milliseconds";
-pattern heartbeat(cnt:int)
+
+pattern heartbeat(cnt:lng)
 address CQheartbeat
 comment "Awake all queries after cnt milliseconds";
 
diff --git a/sql/backends/monet5/sql_cquery.c b/sql/backends/monet5/sql_cquery.c
--- a/sql/backends/monet5/sql_cquery.c
+++ b/sql/backends/monet5/sql_cquery.c
@@ -375,7 +375,7 @@ CQerror(Client cntxt, MalBlkPtr mb, MalS
 
        idx = CQlocate(sch, fcn);
        if( idx == pnettop)
-               throw(SQL,"cquery.error","The continuous procedure %s.%s is not 
accessible\n",sch,fcn);
+               throw(SQL,"cquery.error","The continuous query %s.%s is not 
accessible\n",sch,fcn);
 
        pnet[idx].error = GDKstrdup(error);
        if(pnet[idx].error == NULL)
@@ -396,9 +396,9 @@ CQshow(Client cntxt, MalBlkPtr mb, MalSt
 
        idx = CQlocate(sch, fcn);
        if( idx == pnettop)
-               throw(SQL,"cquery.show","The continuous procedure %s.%s is not 
accessible\n",sch,fcn);
+               throw(SQL,"cquery.show","The continuous query %s.%s is not 
accessible\n",sch,fcn);
 
-       printFunction(cntxt->fdout, pnet[idx].mb, 0, LIST_MAL_NAME | 
LIST_MAL_VALUE  | LIST_MAL_MAPI);
+       printFunction(cntxt->fdout, pnet[idx].mb, 0, LIST_MAL_NAME | 
LIST_MAL_VALUE | LIST_MAL_MAPI);
        return MAL_SUCCEED;
 }
 
@@ -502,11 +502,12 @@ CQregister(Client cntxt, MalBlkPtr mb, M
                msg = createException(SQL,"cquery.register",SQLSTATE(42000) 
"The heartbeats value must be non negative\n");
                goto finish;
        }
-       if(start_atom && (msg = convert_atom_into_unix_timestamp(start_atom, 
&start_at_parsed)) != MAL_SUCCEED){
+       if(start_atom && (msg = convert_atom_into_unix_timestamp(start_atom->a, 
&start_at_parsed)) != MAL_SUCCEED){
                goto finish;
        }
        /**
-        * We are using GDKusec() to check if the query is enable to fire, so 
we have to convert into microseconds
+        * We are using GDKunix_timestamp_usec() to check if the query is 
enable to fire, so we have to convert into
+        * microseconds
         */
        start_at_parsed *= 1000;
 
@@ -635,7 +636,8 @@ CQregister(Client cntxt, MalBlkPtr mb, M
        }
        pnet[pnettop].cycles = cycles;
        pnet[pnettop].beats = SET_HEARTBEATS(heartbeats);
-       pnet[pnettop].run = start_at_parsed;
+       //subtract the beats value so the CQ will start at the precise moment
+       pnet[pnettop].run = start_at_parsed - (pnet[pnettop].beats > 0 ? 
pnet[pnettop].beats : 0);
        pnet[pnettop].seen = *timestamp_nil;
        pnet[pnettop].status = CQWAIT;
        pnettop++;
@@ -675,7 +677,7 @@ CQresumeInternal(Client cntxt, MalBlkPtr
                        msg = 
createException(SQL,"cquery.resume",SQLSTATE(42000) "The heartbeats value must 
be non negative\n");
                        goto finish;
                }
-               if(start_atom && (msg = 
convert_atom_into_unix_timestamp(start_atom, &start_at_parsed)) != MAL_SUCCEED){
+               if(start_atom && (msg = 
convert_atom_into_unix_timestamp(start_atom->a, &start_at_parsed)) != 
MAL_SUCCEED){
                        goto finish;
                }
                start_at_parsed *= 1000;
@@ -709,9 +711,8 @@ CQresumeInternal(Client cntxt, MalBlkPtr
        pnet[idx].status = CQWAIT;
        if(with_alter) {
                pnet[idx].cycles = cycles;
-               if(start_at_parsed > 0)
-                       pnet[idx].run = start_at_parsed;
                pnet[idx].beats = SET_HEARTBEATS(heartbeats);
+               pnet[idx].run = start_at_parsed - (pnet[idx].beats > 0 ? 
pnet[idx].beats : 0);
        }
 
        /* start the scheduler if needed */
@@ -907,6 +908,45 @@ CQpauseAll(Client cntxt, MalBlkPtr mb, M
 }
 
 str
+CQbeginAt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+       str sch, fcn, msg = MAL_SUCCEED;
+       int idx=0, last;
+       lng delay;
+       (void) cntxt;
+       (void) mb;
+
+       MT_lock_set(&ttrLock);
+       last = pnettop;
+       if( pci->argc >2){
+               sch = *getArgReference_str(stk,pci,1);
+               fcn = *getArgReference_str(stk,pci,2);
+               idx = CQlocate(sch, fcn);
+               if( idx == pnettop) {
+                       msg = createException(SQL,"cquery.begintat",
+                                                                 
SQLSTATE(3F000) "The continuous query %s.%s not accessible\n",sch,fcn);
+                       goto finish;
+               }
+               last = idx+1;
+               delay = *getArgReference_lng(stk,pci,3);
+       } else
+               delay = *getArgReference_lng(stk,pci,1);
+#ifdef DEBUG_CQUERY
+       fprintf(stderr, "#set begin at \n");
+#endif
+       if(delay < 0){
+               msg = createException(SQL,"cquery.begintat",SQLSTATE(42000) 
"The delay value must be non negative\n");
+               goto finish;
+       }
+       for( ; idx < last; idx++)
+               pnet[idx].run = delay - (pnet[idx].beats > 0 ? pnet[idx].beats 
: 0);
+
+       finish:
+       MT_lock_unset(&ttrLock);
+       return msg;
+}
+
+str
 CQcycles(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
        str sch, fcn, msg = MAL_SUCCEED;
@@ -922,7 +962,7 @@ CQcycles(Client cntxt, MalBlkPtr mb, Mal
                idx = CQlocate(sch, fcn);
                if( idx == pnettop) {
                        msg = createException(SQL,"cquery.cycles",
-                                                                 
SQLSTATE(3F000) "The continuous procedure %s.%s not accessible\n",sch,fcn);
+                                                                 
SQLSTATE(3F000) "The continuous query %s.%s not accessible\n",sch,fcn);
                        goto finish;
                }
                last = idx+1;
@@ -948,7 +988,8 @@ str
 CQheartbeat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
        str sch, fcn, msg = MAL_SUCCEED;
-       int heartbeats, j, there_is_window_constraint, idx=0, last= pnettop;
+       int j, there_is_window_constraint, idx=0, last= pnettop;
+       lng heartbeats;
        (void) cntxt;
        (void) mb;
 
@@ -959,16 +1000,16 @@ CQheartbeat(Client cntxt, MalBlkPtr mb, 
                idx = CQlocate(sch, fcn);
                if( idx == pnettop) {
                        msg = createException(SQL,"cquery.heartbeat",
-                                                                 
SQLSTATE(3F000) "The continuous procedure %s.%s not accessible\n",sch,fcn);
+                                                                 
SQLSTATE(3F000) "The continuous query %s.%s not accessible\n",sch,fcn);
                        goto finish;
                }
                last = idx+1;
-               heartbeats = *getArgReference_int(stk,pci,3);
+               heartbeats = *getArgReference_lng(stk,pci,3);
 #ifdef DEBUG_CQUERY
                fprintf(stderr, "#set the heartbeat of %s.%s to 
%d\n",sch,fcn,beats);
 #endif
        } else{
-               heartbeats = *getArgReference_int(stk,pci,1);
+               heartbeats = *getArgReference_lng(stk,pci,1);
 #ifdef DEBUG_CQUERY
                fprintf(stderr, "#set the heartbeat %d ms\n",beats);
 #endif
@@ -993,7 +1034,13 @@ CQheartbeat(Client cntxt, MalBlkPtr mb, 
        }
 
        for( ; idx < last; idx++){
-               pnet[idx].beats = SET_HEARTBEATS(heartbeats);
+               int new_hearbeats = SET_HEARTBEATS(heartbeats);
+               if(new_hearbeats > pnet[idx].beats) { //has to do the alignment 
of the starting point
+                       pnet[idx].run -= (new_hearbeats - pnet[idx].beats);
+               } else {
+                       pnet[idx].run += (pnet[idx].beats - new_hearbeats);
+               }
+               pnet[idx].beats = new_hearbeats;
        }
 
        finish:
@@ -1162,7 +1209,7 @@ CQexecute( Client cntxt, int idx)
 
 #ifdef DEBUG_CQUERY
        fprintf(stderr, "#cquery.execute %s.%s locked\n",node->mod, node->fcn);
-       fprintFunction(stderr, node->mb, 0, LIST_MAL_NAME | LIST_MAL_VALUE  | 
LIST_MAL_MAPI);
+       fprintFunction(stderr, node->mb, 0, LIST_MAL_NAME | LIST_MAL_VALUE | 
LIST_MAL_MAPI);
 #endif
 
        msg = runMALsequence(cntxt, node->mb, 1, 0, node->stk, 0, 0);
@@ -1205,7 +1252,7 @@ CQscheduler(void *dummy)
                   come back. We also only have to check the places that are 
marked
                   non empty. You can only trigger on empty baskets using a 
heartbeat */
                memset((void*) claimed, 0, sizeof(claimed));
-               now = GDKusec();
+               now = GDKunix_timestamp_usec();
                pntasks=0;
                MT_lock_set(&ttrLock); // analysis should be done with 
exclusive access
                for (k = i = 0; i < pnettop; i++)
@@ -1402,7 +1449,7 @@ CQstartScheduler(void)
                throw(MAL, "cquery.startScheduler",SQLSTATE(HY001) "Could not 
initialize CQscheduler\n");
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to