rrs-commit: r31 - trunk

decibel at decibel.org decibel at decibel.org
Sun Mar 6 20:56:42 GMT 2005


Author: decibel
Date: Sun Mar  6 20:56:41 2005
New Revision: 31

Modified:
   trunk/rrs_functions.sql
Log:
Linear estimation formula was screwed up. Add min and max data interval settings. Force settings to be something if not set.

Modified: trunk/rrs_functions.sql
==============================================================================
--- trunk/rrs_functions.sql	(original)
+++ trunk/rrs_functions.sql	Sun Mar  6 20:56:41 2005
@@ -36,7 +36,7 @@
     END IF;
 
     -- remember when we started for later
-    v_start_time := current_timestamp;
+    v_start_time := rrs.tod();
 
     -- make sure all the buckets are up to date
     v_total_rows := rrs.update_buckets( v_start_time );
@@ -322,8 +322,8 @@
                 v_first_end_time := rrs.interval_time( v_first_end_time, v_rrs.time_per_bucket) + v_rrs.time_per_bucket;
 
                 -- Figure out our end time. This is an expensive routine, so don''t do it if we''re close to caught up
-                IF v_first_end_time > current_timestamp - rrs.setting_get( ''target length'' )::interval * 3 THEN
-                    v_last_end_time := current_timestamp;
+                IF v_first_end_time > rrs.tod() - rrs.setting_get( ''target length'' )::interval * 3 THEN
+                    v_last_end_time := rrs.tod();
                 ELSE
                     v_last_end_time := calculate_end_time( v_first_end_time, p_start_time );
                 END IF;
@@ -391,58 +391,104 @@
     p_first_end_time ALIAS FOR $1;
     p_start_time ALIAS FOR $2;
 
+    r record;
+    v_desired_run_time interval;
+    v_min_interval interval;
+    v_max_interval interval;
     v_data_interval rrs.history_data_interval.data_interval%TYPE;
     v_last_end_time rrs.bucket.end_time%TYPE;
 BEGIN
+    v_desired_run_time := rrs.setting_get(''desired run time'');
+    IF v_desired_run_time IS NULL THEN
+        v_desired_run_time := rrs.setting_set( ''desired run time'', ''1 minute'' );
+        v_desired_run_time := rrs.setting_get(''desired run time'');
+        RAISE WARNING ''calculate_end_time: WARNING desired run time not set, setting to %'', v_desired_run_time;
+    END IF;
+
+    v_min_interval = rrs.setting_get(''minimum data interval'');
+    IF v_min_interval IS NULL THEN
+        v_min_interval = rrs.setting_set(
+                                            ''minimum data interval''
+                                            , ( v_desired_run_time * 10 )::text
+                                        )
+        ;
+        v_min_interval = rrs.setting_get(''minimum data interval'');
+        RAISE WARNING ''calculate_end_time: WARNING minimum data interval not set, setting to %'', v_min_interval;
+    END IF;
+
+    v_max_interval = rrs.setting_get(''maximum data interval'');
+    IF v_max_interval IS NULL THEN
+        v_max_interval = rrs.setting_set(
+                                            ''maximum data interval''
+                                            , ( v_min_interval * 1000 )::text
+                                        )
+        ;
+        v_max_interval = rrs.setting_get(''maximum data interval'');
+        RAISE WARNING ''calculate_end_time: WARNING maximum data interval not set, setting to %'', v_max_interval;
+    END IF;
+
+    IF v_max_interval < v_min_interval THEN
+        RAISE EXCEPTION ''calculate_end_time: EXCEPTION! maximum data interval(%) < minimum data interval(%)'', v_max_interval, v_min_interval;
+    END IF;
+
+    RAISE DEBUG ''calculate_end_time BEGIN: p_first_end_time %, p_start_time %, desired run time %, minimum data interval %, maximum data interval %'', p_first_end_time, p_start_time, v_desired_run_time, v_min_interval;
+
     /*
     To calculate the end time we build a linear estimation (http://mathworld.wolfram.com/LeastSquaresFitting.html).
     This gives as a straight line of the formula y = ax + b. The formulas for a and b are
 
+    a = ( sum(y) * sum(x^2) - sum(x) * sum(xy) ) / ( count(*) * sum(x^2) - count(*) * sum(x)^2 )
     b = ( sum(xy) - n * sum(x) * sum(y) ) / ( sum(x^2) - n * sum(x)^2 )
 
-    a = sum(y) - b * sum(x)
-
     If x is runtime and y is data interval, our desired data_interval would be y = ax + b
-        = ( sum(y) - b * sum(x) ) * x + b
 
     */
     
-    SELECT INTO v_data_interval
-            coalesce(
-                    seconds_to_interval(
-                            ( sum_y - b * sum_x )
-                            * rrs.interval_to_seconds( rrs.setting_get(''desired run time'')::interval )
-                            + b
-                        )
-                    , rrs.setting_get(''desired run time'')::interval
-                )
+    SELECT INTO r
+            CASE WHEN ( count(*) * sum(x*x) - count(*) * sum(x)^2 ) = 0
+                    THEN 1
+                    ELSE ( sum(y) * sum(x*X) - sum(x) * sum(x*y) ) / ( count(*) * sum(x*x) - count(*) * sum(x)^2 )
+                    END
+                AS a
+            , CASE WHEN ( sum(x*x) - count(*) * sum(x) * sum(x) ) = 0
+                THEN 1
+                ELSE ( sum( x * y ) - count(*) * sum(x) * sum(y) ) / ( sum(x*x) - count(*) * sum(x) * sum(x) )
+                END
+            AS b
         FROM (
-                SELECT sum(x) AS sum_x, sum(y) AS sum_y
-                        , CASE WHEN ( sum(x*x) - count(*) * sum(x) * sum(x) ) = 0
-                            THEN 1
-                            ELSE ( sum( x * y ) - count(*) * sum(x) * sum(y) ) / ( sum(x*x) - count(*) * sum(x) * sum(x) )
-                            END
-                        AS b
-                    FROM (
-                            SELECT rrs.interval_to_seconds(data_interval) AS y
-                                    , rrs.interval_to_seconds( end_time - start_time) AS x
-                                FROM history_data_interval
-                        ) raw
-            ) sums_b
+                SELECT rrs.interval_to_seconds(data_interval) AS y
+                        , rrs.interval_to_seconds( end_time - start_time) AS x
+                    FROM history_data_interval
+            ) raw
     ;
-    IF v_data_interval <= 0 THEN
-        RAISE INFO ''v_data_interval % <= 0, forcing to desired run time'', v_data_interval;
-        v_data_interval = rrs.setting_get(''desired run time'');
+
+    v_data_interval := coalesce( rrs.seconds_to_interval(
+                                        r.a
+                                        * rrs.interval_to_seconds( v_desired_run_time )
+                                        + r.b
+                                    )
+                                , ''0 seconds''::interval )
+    ;
+    RAISE DEBUG ''a=%, b=%, v_data_interval=%'', r.a, r.b, v_data_interval;
+
+    IF v_data_interval < v_min_interval THEN
+        RAISE INFO ''v_data_interval % too low, forcing to minimum interval (%)'', v_data_interval, v_min_interval;
+        v_data_interval := v_min_interval;
+    END IF;
+    IF v_data_interval > v_max_interval THEN
+        RAISE INFO ''v_data_interval % too high, forcing to maximum interval (%)'', v_data_interval, v_max_interval;
+        v_data_interval := v_max_interval;
     END IF;
 
-    -- Now we have an upper limit on how many buckets to process, but we don''t want to go beyond current_timestamp
-    v_last_end_time := min( current_timestamp, p_first_end_time + v_data_interval );
+    -- Now we have an upper limit on how many buckets to process, but we don''t want to go beyond rrs.tod()
+    v_last_end_time := min( rrs.tod(), p_first_end_time + v_data_interval );
 
     -- Log how much time we''ll actually be processing
     INSERT INTO rrs.history_data_interval( start_time, end_time, data_interval )
         VALUES( p_start_time, p_start_time, v_last_end_time - p_first_end_time )
     ;
 
+    RAISE DEBUG ''calculate_end_time RETURN: v_last_end_time %'', v_last_end_time;
     RETURN v_last_end_time;
 END;
 ' LANGUAGE plpgsql;
@@ -523,6 +569,8 @@
 DECLARE
     p_start_time ALIAS FOR $1;
 
+    v_history_length bigint;
+    v_history_data_interval_length bigint;
     v_end_time rrs.history.end_time%TYPE;
     v_min_keep_time rrs.history.start_time%TYPE;
 BEGIN
@@ -530,6 +578,12 @@
     RAISE DEBUG ''log_time: p_start_time %, v_end_time %'', p_start_time, v_end_time;
 
     -- Trim the history table
+    v_history_length := rrs.setting_get( ''history length'' );
+    IF v_history_length IS NULL THEN
+        v_history_length := rrs.setting_set( ''history length'', 100 );
+        v_history_length := rrs.setting_get( ''history length'' );
+        RAISE WARNING ''log_time: WARNING history length not set, setting to %'', v_history_length;
+    END IF;
     SELECT INTO v_min_keep_time
             min( start_time )
         FROM (
@@ -539,7 +593,7 @@
                                 FROM rrs.history
                                 ORDER BY start_time DESC
                         ) ordered
-                    LIMIT rrs.setting_get( ''history length'' )::bigint
+                    LIMIT v_history_length
             ) limited
     ;
     IF FOUND THEN
@@ -553,6 +607,12 @@
     -- IF add_buckets decided not to limit bucket creation, don''t bother processing anything
     IF EXISTS (SELECT * FROM rrs.history_data_interval WHERE start_time = p_start_time) THEN
         -- Trim the history table
+        v_history_data_interval_length := rrs.setting_get( ''history_data_interval length'' );
+        IF v_history_data_interval_length IS NULL THEN
+            v_history_data_interval_length := rrs.setting_set( ''history_data_interval length'', 100 );
+            v_history_data_interval_length := rrs.setting_get( ''history_data_interval length'' );
+            RAISE WARNING ''log_time: WARNING history_data_interval length not set, setting to %'', v_history_data_interval_length;
+        END IF;
         SELECT INTO v_min_keep_time
                 min( start_time )
             FROM (
@@ -562,7 +622,7 @@
                                     FROM rrs.history_data_interval
                                     ORDER BY start_time DESC
                             ) ordered
-                        LIMIT rrs.setting_get( ''history_data_interval length'' )::bigint
+                        LIMIT v_history_data_interval_length
                 ) limited
         ;
         IF FOUND THEN
@@ -629,6 +689,11 @@
 '
     LANGUAGE plpgsql
     SECURITY DEFINER
+;
+
+CREATE OR REPLACE FUNCTION tod() RETURNS timestamptz AS '
+    SELECT timeofday()::timestamptz
+' LANGUAGE sql
 ;
 
 


More information about the rrs-commit mailing list