Ignore:
Timestamp:
Jan 1, 2016, 12:13:34 PM (9 years ago)
Author:
chronos
Message:
  • Modified: stat_functions changed to PHP class.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/stat_functions.php

    r59 r62  
    11<?php
    22
    3 $ValueTypes = array('min', 'avg', 'max');
    4 
    5 function GetMicrotime()
     3include_once('Point.php');
     4
     5class Measure
    66{
    7     list($Usec, $Sec) = explode(" ",microtime());
    8     return ((float)$Usec + (float)$Sec);
    9 }
    10 
    11 function TimeSegment($Level)
    12 {
    13   global $LevelReducing;
    14   return(pow($LevelReducing, $Level) * 60);
    15 }
    16 
    17 function StatTableName($Level)
    18 {
    19   if($Level == 0) return('data');
    20     else return('data_cache');
    21 }
    22 
    23 function AlignTime($Time, $TimeSegment)
    24 {
    25   global $ReferenceTime, $LevelReducing;
    26   return(round(($Time - $ReferenceTime) / $TimeSegment) * $TimeSegment + $ReferenceTime);
    27 }
    28 
    29 function GetMeasureById($Id)
    30 {
    31   global $Database;
    32 
    33   $Result = $Database->select('measure', '*', 'Id='.$Id);
    34   if($Result->num_rows > 0)
    35   {
    36     $Measure = $Result->fetch_array();
    37     if($Measure['Continuity'] == 0) $Measure['ContinuityEnabled'] = 0;  // non continuous
    38       else $Measure['ContinuityEnabled'] = 2;    // continuous graph
    39   } else die('Měřená veličina nenalezena');
    40   return($Measure);
    41 }
    42 
    43 function AddValue($Measure, $Value)
    44 {
    45   global $LevelReducing, $MaxLevel, $Database;
    46 
    47   $Time = time();
    48   //$Value = round($Measure['divider'] * $Value);
    49 
    50   $Result = $Database->select($Measure['DataTable'], '*', 'measure='.$Measure['Id'].' AND level=0 ORDER BY time DESC LIMIT 2');
    51   if($Result->num_rows == 0) $Database->insert($Measure['DataTable'],
    52     array('min' => $Value, 'avg' => $Value, 'max' => $Value, 'level' => 0,
    53     'measure' => $Measure['Id'], 'time' => TimeToMysqlDateTime($Time), 'continuity' => 0));
    54   else if($Result->num_rows == 1) $Database->insert($Measure['DataTable'], array('min' => $Value, 'avg' => $Value, 'max' => $Value, 'level' => 0, 'measure' => $Measure['Id'], 'time' => TimeToMysqlDateTime($Time),
    55     'continuity' => 1));
    56   else {
    57     $LastValue = $Result->fetch_array();
    58     $NextToLastValue = $Result->fetch_array();
    59     if(($Time - MysqlDateTimeToTime($LastValue['time'])) < 0.75 * $Measure['Period'])
    60     {
    61     }
    62     else
    63     {
    64       if(($Time - MysqlDateTimeToTime($LastValue['time'])) < 1.25 * $Measure['Period']) $Continuity = 1;
    65         else $Continuity = 0;
    66       if(($LastValue['avg'] == $NextToLastValue['avg']) and ($LastValue['avg'] == $Value) and
    67         ($LastValue['continuity'] == 1) and ($Continuity == 1))
    68       {
    69         $Database->update($Measure['DataTable'], '(time="'.$LastValue['time'].'") AND '.
    70         '(level=0) AND (measure='.$Measure['Id'].')', array('time' => TimeToMysqlDateTime($Time)));
    71       } else
    72       {
    73         $Database->insert($Measure['DataTable'], array('min' => $Value,
    74           'avg' => $Value, 'max' => $Value, 'level' => 0, 'measure' => $Measure['Id'], 'time' => TimeToMysqlDateTime($Time),
    75           'continuity' => $Continuity));
    76       }
    77     }
    78   }
     7  var $Data;
     8  var $ValueTypes;
     9  var $LevelReducing;
     10  var $Database;
     11  var $MaxLevel;
     12  var $ReferenceTime;
     13  var $Differential;
     14  var $DivisionCount;
     15
     16  function __construct($Database)
     17  {
     18    $this->Id = 0;
     19    $this->ValueTypes = array('min', 'avg', 'max');
     20    $this->Database = &$Database;
     21    $this->LevelReducing = 5;
     22    $this->MaxLevel = 4;
     23    $this->ReferenceTime = 0;
     24    $this->Differential = 0;
     25    $this->DivisionCount = 500;
     26  }
     27
     28  function TimeSegment($Level)
     29  {
     30    return(pow($this->LevelReducing, $Level) * 60);
     31  }
     32
     33  function StatTableName($Level)
     34  {
     35    if($Level == 0) return('data');
     36      else return('data_cache');
     37  }
     38
     39  function AlignTime($Time, $TimeSegment)
     40  {
     41    return(round(($Time - $this->ReferenceTime) / $TimeSegment) * $TimeSegment +
     42      $this->ReferenceTime);
     43  }
     44
     45  function Load($Id)
     46  {
     47    $Result = $this->Database->select('measure', '*', 'Id='.$Id);
     48    if($Result->num_rows > 0)
     49    {
     50      $this->Data = $Result->fetch_array();
     51      if($this->Data['Continuity'] == 0) $this->Data['ContinuityEnabled'] = 0;  // non continuous
     52        else $this->Data['ContinuityEnabled'] = 2;    // continuous graph
     53    } else die('Měřená veličina nenalezena');
     54  }
     55
     56  function AddValue($Value)
     57  {
     58    $Time = time();
     59
     60    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
     61      '(`level`=0) ORDER BY `time` DESC LIMIT 2');
     62    if($Result->num_rows == 0) $this->Database->insert($this->Data['DataTable'],
     63      array('min' => $Value, 'avg' => $Value, 'max' => $Value, 'level' => 0,
     64      'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time), 'continuity' => 0));
     65    else if($Result->num_rows == 1) $this->Database->insert($this->Data['DataTable'],
     66      array('min' => $Value, 'avg' => $Value, 'max' => $Value, 'level' => 0,
     67      'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time),
     68      'continuity' => 1));
     69    else {
     70      $LastValue = $Result->fetch_array();
     71      $NextToLastValue = $Result->fetch_array();
     72      if(($Time - MysqlDateTimeToTime($LastValue['time'])) < 0.75 * $this->Data['Period'])
     73      {
     74      }
     75      else
     76      {
     77        if(($Time - MysqlDateTimeToTime($LastValue['time'])) < 1.25 * $this->Data['Period']) $Continuity = 1;
     78          else $Continuity = 0;
     79        if(($LastValue['avg'] == $NextToLastValue['avg']) and ($LastValue['avg'] == $Value) and
     80          ($LastValue['continuity'] == 1) and ($Continuity == 1))
     81        {
     82          $this->Database->update($this->Data['DataTable'], '(time="'.$LastValue['time'].'") AND '.
     83          '(level=0) AND (measure='.$this->Data['Id'].')', array('time' => TimeToMysqlDateTime($Time)));
     84        } else
     85        {
     86          $this->Database->insert($this->Data['DataTable'], array('min' => $Value,
     87            'avg' => $Value, 'max' => $Value, 'level' => 0, 'measure' => $this->Data['Id'], 'time' => TimeToMysqlDateTime($Time),
     88            'continuity' => $Continuity));
     89        }
     90      }
     91    }
    7992
    8093    // Update levels
    81     for($Level = 1; $Level <= $MaxLevel; $Level++)
    82     {
    83       $TimeSegment = TimeSegment($Level);
    84       $EndTime = AlignTime($Time, $TimeSegment);
     94    for($Level = 1; $Level <= $this->MaxLevel; $Level++)
     95    {
     96      $TimeSegment = $this->TimeSegment($Level);
     97      $EndTime = $this->AlignTime($Time, $TimeSegment);
    8598      //if($EndTime < $Time) $EndTime = $EndTime + $TimeSegment;
    8699      $StartTime = $EndTime - $TimeSegment;
     
    88101      // Load values in time range
    89102      $Values = array();
    90       $Result = $Database->select($Measure['DataTable'], '*', 'time > "'.TimeToMysqlDateTime($StartTime).'" AND time < "'.
    91         TimeToMysqlDateTime($EndTime).'" AND measure='.$Measure['Id'].' AND level='.($Level-1).' ORDER BY time');
     103      $Result = $this->Database->select($this->Data['DataTable'], '*', '(`time` > "'.TimeToMysqlDateTime($StartTime).'") AND '.
     104        '(`time` < "'.TimeToMysqlDateTime($EndTime).'") AND '.
     105        '(`measure`='.$this->Data['Id'].') AND (`level`='.($Level - 1).') ORDER BY `time`');
    92106      while($Row = $Result->fetch_array())
    93107      {
     
    95109        $Values[] = $Row;
    96110      }
    97       //array_pop($Values);     
     111      //array_pop($Values);
    98112
    99113      // Load subsidary values
    100       $Values = array_merge(LoadLeftSideValue($Level-1, $Measure, $StartTime), $Values, LoadRightSideValue($Level-1, $Measure, $EndTime));
    101 
    102       $Point = ComputeOneValue($StartTime, $EndTime, $Values, $Measure, $Level);
    103 
    104       $Database->delete($Measure['DataTable'], '(time > "'.TimeToMysqlDateTime($StartTime).'") AND
    105         (time < "'.TimeToMysqlDateTime($EndTime).'") AND measure='.$Measure['Id'].' AND level='.$Level);
    106       $Continuity = $Values[1]['continuity'];   
    107       $Database->insert($Measure['DataTable'], array('level' => $Level, 'measure' => $Measure['Id'], 'min' => $Point['min'],
    108         'avg' => $Point['avg'], 'max' => $Point['max'], 'continuity' => $Continuity, 'time' => TimeToMysqlDateTime($StartTime+($EndTime-$StartTime)/2)));
    109 
    110     }
    111 }
    112 
    113 function Interpolation($X1, $Y1, $X2, $Y2, $X)
    114 {
    115   $Y = ($Y2 - $Y1) / ($X2 - $X1) * ($X - $X1) + $Y1;
    116   return($Y);
    117 }
    118 
    119 /* Compute one value for upper time level from multiple values */
    120 function ComputeOneValue($LeftTime, $RightTime, $Values, $Measure, $Level)
    121 {
    122   global $ValueTypes, $Differential;
    123 
    124   $NewValue = array('min' => +1000000000000000000, 'avg' => 0, 'max' => -1000000000000000000);
    125 
    126   // Trim outside parts
    127   foreach($ValueTypes as $ValueType)
    128   {
    129     $Values[0][$ValueType] = Interpolation($Values[0]['time'], $Values[0][$ValueType],
    130       $Values[1]['time'], $Values[1][$ValueType], $LeftTime);
    131   }
    132   $Values[0]['time'] = $LeftTime;
    133   foreach($ValueTypes as $ValueType)
    134   {
    135     $Values[count($Values) - 1][$ValueType] = Interpolation($Values[count($Values) - 2]['time'],
    136       $Values[count($Values) - 2][$ValueType],
    137       $Values[count($Values) - 1]['time'], $Values[count($Values) - 1][$ValueType], $RightTime);
    138   }
    139   $Values[count($Values) - 1]['time'] = $RightTime;
    140 
    141   // Perform computation
    142   foreach($ValueTypes as $ValueType)
    143   {
    144     // Compute new value
    145     for($I = 0; $I < (count($Values) - 1); $I++)
    146     {
    147       if($ValueType == 'avg')
    148       {
    149         if($Values[$I + 1]['continuity'] == $Measure['ContinuityEnabled']);
    150           else if($Differential == 0)
     114      $Values = array_merge(
     115        $this->LoadLeftSideValue($Level - 1, $StartTime),
     116        $Values,
     117        $this->LoadRightSideValue($Level - 1, $EndTime));
     118
     119      $Point = $this->ComputeOneValue($StartTime, $EndTime, $Values, $Level);
     120
     121      $this->Database->delete($this->Data['DataTable'], '(time > "'.TimeToMysqlDateTime($StartTime).'") AND
     122        (time < "'.TimeToMysqlDateTime($EndTime).'") AND measure='.$this->Data['Id'].' AND level='.$Level);
     123      $Continuity = $Values[1]['continuity'];
     124      $this->Database->insert($this->Data['DataTable'], array('level' => $Level, 'measure' => $this->Data['Id'], 'min' => $Point['min'],
     125        'avg' => $Point['avg'], 'max' => $Point['max'], 'continuity' => $Continuity,
     126        'time' => TimeToMysqlDateTime($StartTime + ($EndTime - $StartTime) / 2)));
     127
     128    }
     129  }
     130
     131  /* Compute one value for upper time level from multiple values */
     132  function ComputeOneValue($LeftTime, $RightTime, $Values, $Level)
     133  {
     134    $NewValue = array('min' => +1000000000000000000, 'avg' => 0, 'max' => -1000000000000000000);
     135
     136    // Trim outside parts
     137    foreach($this->ValueTypes as $ValueType)
     138    {
     139      $Values[0][$ValueType] = Interpolation(NewPoint($Values[0]['time'], $Values[0][$ValueType]),
     140        NewPoint($Values[1]['time'], $Values[1][$ValueType]), $LeftTime);
     141    }
     142    $Values[0]['time'] = $LeftTime;
     143    foreach($this->ValueTypes as $ValueType)
     144    {
     145      $Values[count($Values) - 1][$ValueType] = Interpolation(NewPoint($Values[count($Values) - 2]['time'],
     146        $Values[count($Values) - 2][$ValueType]),
     147        NewPoint($Values[count($Values) - 1]['time'], $Values[count($Values) - 1][$ValueType]),
     148        $RightTime);
     149    }
     150    $Values[count($Values) - 1]['time'] = $RightTime;
     151
     152    // Perform computation
     153    foreach($this->ValueTypes as $ValueType)
     154    {
     155      // Compute new value
     156      for($I = 0; $I < (count($Values) - 1); $I++)
     157      {
     158        if($ValueType == 'avg')
     159        {
     160          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled']);
     161            else if($this->Differential == 0)
     162            {
     163              $NewValue[$ValueType] = $NewValue[$ValueType] + ($Values[$I + 1]['time'] - $Values[$I]['time']) *
     164                (($Values[$I + 1][$ValueType] - $Values[$I][$ValueType]) / 2 + $Values[$I][$ValueType]);
     165            } else {
     166              $NewValue[$ValueType] = $NewValue[$ValueType] + ($Values[$I + 1]['time'] - $Values[$I]['time']) *
     167               (($Values[$I + 1][$ValueType] - $Values[$I][$ValueType]) / 2);
     168            }
     169        }
     170        else if($ValueType == 'max')
     171        {
     172          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled'])
    151173          {
    152             $NewValue[$ValueType] = $NewValue[$ValueType] + ($Values[$I + 1]['time'] - $Values[$I]['time']) *
    153               (($Values[$I + 1][$ValueType] - $Values[$I][$ValueType]) / 2 + $Values[$I][$ValueType]);
    154           } else {
    155             $NewValue[$ValueType] = $NewValue[$ValueType] + ($Values[$I + 1]['time'] - $Values[$I]['time']) *
    156              (($Values[$I + 1][$ValueType] - $Values[$I][$ValueType]) / 2);
     174            if(0 > $NewValue[$ValueType]) $NewValue[$ValueType] = 0;
    157175          }
    158       }
    159       else if($ValueType == 'max')
    160       {
    161         if($Values[$I + 1]['continuity'] == $Measure['ContinuityEnabled'])
    162         {
    163           if(0 > $NewValue[$ValueType]) $NewValue[$ValueType] = 0;
    164         }
    165         else
    166         {
    167           if($Differential == 0)
     176          else
    168177          {
    169             if($Values[$I + 1][$ValueType] > $NewValue[$ValueType]) $NewValue[$ValueType] = $Values[$I + 1][$ValueType];
     178            if($this->Differential == 0)
     179            {
     180              if($Values[$I + 1][$ValueType] > $NewValue[$ValueType]) $NewValue[$ValueType] = $Values[$I + 1][$ValueType];
     181            } else {
     182              $Difference = $Values[$I + 1][$ValueType] - $Values[$I][$ValueType];
     183              if($Difference > $NewValue[$ValueType]) $NewValue[$ValueType] = $Difference;
     184            }
     185          }
     186        }
     187        else if($ValueType == 'min')
     188        {
     189          if($Values[$I + 1]['continuity'] == $this->Data['ContinuityEnabled'])
     190          {
     191            if(0 < $NewValue[$ValueType]) $NewValue[$ValueType] = 0;
    170192          } else {
    171             $Difference = $Values[$I + 1][$ValueType] - $Values[$I][$ValueType];
    172             if($Difference > $NewValue[$ValueType]) $NewValue[$ValueType] = $Difference;
     193            if($this->Differential == 0)
     194            {
     195              if($Values[$I + 1][$ValueType] < $NewValue[$ValueType]) $NewValue[$ValueType] = $Values[$I + 1][$ValueType];
     196            } else {
     197              $Difference = $Values[$I + 1][$ValueType] - $Values[$I][$ValueType];
     198              if($Difference < $NewValue[$ValueType]) $NewValue[$ValueType] = $Difference;
     199            }
    173200          }
    174201        }
    175202      }
    176       else if($ValueType == 'min')
    177       {
    178         if($Values[$I + 1]['continuity'] == $Measure['ContinuityEnabled'])
    179         {
    180           if(0 < $NewValue[$ValueType]) $NewValue[$ValueType] = 0;
    181         } else {
    182           if($Differential == 0)
    183           {
    184             if($Values[$I + 1][$ValueType] < $NewValue[$ValueType]) $NewValue[$ValueType] = $Values[$I + 1][$ValueType];
    185           } else {
    186             $Difference = $Values[$I + 1][$ValueType] - $Values[$I][$ValueType];
    187             if($Difference < $NewValue[$ValueType]) $NewValue[$ValueType] = $Difference;
    188           }
    189         }
    190       }
    191     }
    192     $NewValue[$ValueType] = $NewValue[$ValueType];
    193   }
    194   //if(($RightTime - $LeftTime) > 0)
    195   if($Measure['Cumulative'] == 0)
    196   {
    197     $NewValue['avg'] = $NewValue['avg'] / ($RightTime - $LeftTime);
    198   }
    199   return($NewValue);
    200 }
    201 
    202 function GetTimeRange($Measure, $Level)
    203 {
    204   global $Debug, $Database;
    205 
    206   // Get first and last time
    207   $Result = $Database->select($Measure['DataTable'], '*', 'measure='.$Measure['Id'].' AND level='.$Level.' ORDER BY time LIMIT 1');
    208   if($Result->num_rows > 0)
    209   {
    210     $Row = $Result->fetch_array();
    211     $AbsoluteLeftTime = MysqlDateTimeToTime($Row['time']);
    212   } else $AbsoluteLeftTime = 0;
    213 
    214   $Result = $Database->select($Measure['DataTable'], '*', 'measure='.$Measure['Id'].' AND level='.$Level.' ORDER BY time DESC LIMIT 1');
    215   if($Result->num_rows > 0)
    216   {
    217     $Row = $Result->fetch_array();
    218     $AbsoluteRightTime = MysqlDateTimeToTime($Row['time']);
    219   } else $AbsoluteRightTime = 0;
    220 
    221   if($Debug)
    222   {
    223     echo('AbsoluteLeftTime: '.$AbsoluteLeftTime.'('.TimeToMysqlDateTime($AbsoluteLeftTime).')<br>');
    224     echo('AbsoluteRightTime: '.$AbsoluteRightTime.'('.TimeToMysqlDateTime($AbsoluteRightTime).')<br>');
    225   }
    226   return(array('left' => $AbsoluteLeftTime, 'right' => $AbsoluteRightTime));
    227 }
    228 
    229 function LoadRightSideValue($Level, $Measure, $Time)
    230 {
    231   global $Debug, $Database;
    232  
    233   $Result = array();
    234   $DbResult = $Database->select($Measure['DataTable'], '*', '(time > "'.TimeToMysqlDateTime($Time).'") AND (measure='.$Measure['Id'].') AND (level='.$Level.') ORDER BY time ASC LIMIT 1');
    235   if($DbResult->num_rows > 0)
    236   {
    237     $Row = $DbResult->fetch_array();
    238     $Row['time'] = MysqlDateTimeToTime($Row['time']);
    239     return(array($Row));
    240   }
    241   else
    242   {
    243     //$Time = $Values[count($Values)-1]['time'] + 60;
    244     //array_push($Values, array('time' => $Time, 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
    245     $Result[] = array('time' => ($Time + TimeSegment($Level)), 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0);
    246     $DbResult = $Database->select($Measure['DataTable'], '*', '(time < "'.TimeToMysqlDateTime($Time).'") AND (measure='.$Measure['Id'].') AND (level='.$Level.') ORDER BY time DESC LIMIT 1');
     203      $NewValue[$ValueType] = $NewValue[$ValueType];
     204    }
     205    //if(($RightTime - $LeftTime) > 0)
     206    if($this->Data['Cumulative'] == 0)
     207    {
     208      $NewValue['avg'] = $NewValue['avg'] / ($RightTime - $LeftTime);
     209    }
     210    return($NewValue);
     211  }
     212
     213  function GetTimeRange($Level)
     214  {
     215    // Get first and last time
     216    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
     217      '(`level`='.$Level.') ORDER BY `time` LIMIT 1');
     218    if($Result->num_rows > 0)
     219    {
     220      $Row = $Result->fetch_array();
     221      $AbsoluteLeftTime = MysqlDateTimeToTime($Row['time']);
     222    } else $AbsoluteLeftTime = 0;
     223
     224    $Result = $this->Database->select($this->Data['DataTable'], '*', '(`measure`='.$this->Data['Id'].') AND '.
     225      '(`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
     226    if($Result->num_rows > 0)
     227    {
     228      $Row = $Result->fetch_array();
     229      $AbsoluteRightTime = MysqlDateTimeToTime($Row['time']);
     230    } else $AbsoluteRightTime = 0;
     231
     232    return(array('left' => $AbsoluteLeftTime, 'right' => $AbsoluteRightTime));
     233  }
     234
     235  function LoadRightSideValue($Level, $Time)
     236  {
     237    $Result = array();
     238    $DbResult = $this->Database->select($this->Data['DataTable'], '*', '(time > "'.TimeToMysqlDateTime($Time).'") AND (measure='.$this->Data['Id'].') AND (level='.$Level.') ORDER BY time ASC LIMIT 1');
    247239    if($DbResult->num_rows > 0)
    248240    {
    249241      $Row = $DbResult->fetch_array();
    250       array_unshift($Result, array('time' => (MysqlDateTimeToTime($Row['time'])+10), 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
    251     }
    252    // if($Debug) print_r($Result);
    253     return($Result);
    254   }
    255 }
    256 
    257 function LoadLeftSideValue($Level, $Measure, $Time)
    258 {
    259   global $Debug, $Database;
    260 
    261   $Result = array();
    262   $DbResult = $Database->select($Measure['DataTable'], '*', '(time < "'.TimeToMysqlDateTime($Time).'") AND (measure='.$Measure['Id'].') AND (level='.$Level.') ORDER BY time DESC LIMIT 1');
    263   if($DbResult->num_rows > 0)
    264   {
    265     $Row = $DbResult->fetch_array();
    266     $Row['time'] = MysqlDateTimeToTime($Row['time']);
    267     return(array($Row));
    268   } else {
    269     //$Time = $Values[0]['time'] - 60;
    270     //array_unshift($Values, array('time' => $Time, 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
    271     $Result[] = array('time' => ($Time - TimeSegment($Level)), 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0);
    272 
    273     $DbResult = $Database->select($Measure['DataTable'], '*', '(time > "'.TimeToMysqlDateTime($Time).'") AND (measure='.$Measure['Id'].') AND (level='.$Level.') ORDER BY time ASC LIMIT 1');
     242      $Row['time'] = MysqlDateTimeToTime($Row['time']);
     243      return(array($Row));
     244    }
     245    else
     246    {
     247      //$Time = $Values[count($Values)-1]['time'] + 60;
     248      //array_push($Values, array('time' => $Time, 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
     249      $Result[] = array('time' => ($Time + $this->TimeSegment($Level)), 'min' => 0,
     250        'avg' => 0, 'max' => 0, 'continuity' => 0);
     251      $DbResult = $this->Database->select($this->Data['DataTable'], '*',
     252        '(`time` < "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
     253        'AND (`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
     254      if($DbResult->num_rows > 0)
     255      {
     256        $Row = $DbResult->fetch_array();
     257        array_unshift($Result, array('time' => (MysqlDateTimeToTime($Row['time']) + 10),
     258          'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
     259      }
     260      return($Result);
     261    }
     262  }
     263
     264  function LoadLeftSideValue($Level, $Time)
     265  {
     266    $Result = array();
     267    $DbResult = $this->Database->select($this->Data['DataTable'], '*',
     268      '(`time` < "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
     269      'AND (`level`='.$Level.') ORDER BY `time` DESC LIMIT 1');
    274270    if($DbResult->num_rows > 0)
    275271    {
    276272      $Row = $DbResult->fetch_array();
    277       array_push($Result, array('time' => (MysqlDateTimeToTime($Row['time']) - 10),
    278         'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
    279     }
    280     return($Result);
    281   }
    282 }
    283 
    284 function GetValues($Measure, $TimeFrom, $TimeTo, $Level)
    285 {
    286   global $DivisionCount, $Debug, $Database;
    287 
    288   if($Debug) echo('TimeFrom: '.$TimeFrom.'('.TimeToMysqlDateTime($TimeFrom).')<br>');
    289   if($Debug) echo('TimeTo: '.$TimeTo.'('.TimeToMysqlDateTime($TimeTo).')<br>');
    290 
    291   //$AbsoluteTime = GetTimeRange($MeasureId);
    292 
    293 //  if(($TimeFrom > $AbsoluteLeftTime) and ($TimeStart < $AbsoluteRightTime) and
     273      $Row['time'] = MysqlDateTimeToTime($Row['time']);
     274      return(array($Row));
     275    } else {
     276      //$Time = $Values[0]['time'] - 60;
     277      //array_unshift($Values, array('time' => $Time, 'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
     278      $Result[] = array('time' => ($Time - $this->TimeSegment($Level)), 'min' => 0,
     279        'avg' => 0, 'max' => 0, 'continuity' => 0);
     280
     281      $DbResult = $this->Database->select($this->Data['DataTable'], '*',
     282        '(`time` > "'.TimeToMysqlDateTime($Time).'") AND (`measure`='.$this->Data['Id'].') '.
     283        'AND (`level`='.$Level.') ORDER BY `time` ASC LIMIT 1');
     284      if($DbResult->num_rows > 0)
     285      {
     286        $Row = $DbResult->fetch_array();
     287        array_push($Result, array('time' => (MysqlDateTimeToTime($Row['time']) - 10),
     288          'min' => 0, 'avg' => 0, 'max' => 0, 'continuity' => 0));
     289      }
     290      return($Result);
     291    }
     292  }
     293
     294  function GetValues($TimeFrom, $TimeTo, $Level)
     295  {
     296  //$AbsoluteTime = GetTimeRange($this->DataId);
     297
     298//  if(($TimeFrom > $AbsoluteLeftTime) and ($TimeStart < $AbsoluteRightTime) and
    294299//    ($TimeTo > $AbsoluteLeftTime) and ($TimeTo < $AbsoluteRightTime))
    295300//  {
    296301
    297   // Load values in time range
    298   $Result = $Database->select($Measure['DataTable'], 'time, min, avg, max, continuity', 'time > "'.TimeToMysqlDateTime($TimeFrom).'" AND time < "'.
    299     TimeToMysqlDateTime($TimeTo).'" AND measure='.$Measure['Id'].' AND level='.$Level.' ORDER BY time');
    300   $Values = array();
    301   while($Row = $Result->fetch_array())
    302   {
    303     $Values[] = array('time' => MysqlDateTimeToTime($Row['time']), 'min' => $Row['min'], 'avg' => $Row['avg'], 'max' => $Row['max'], 'continuity' => $Row['continuity']);
    304   }
    305  // array_pop($Values);
    306   if($Debug) echo('Item count: '.count($Values));
    307 
    308   $Points = array();
    309   if(count($Values) > 0)
    310   {
    311     $Values = array_merge(LoadLeftSideValue($Level, $Measure, $TimeFrom), $Values, LoadRightSideValue($Level, $Measure, $TimeTo));
    312 
    313     $StartIndex = 0;
     302    // Load values in time range
     303    $Result = $this->Database->select($this->Data['DataTable'], '`time`, `min`, `avg`, `max`, `continuity`',
     304      '(`time` > "'.TimeToMysqlDateTime($TimeFrom).'") AND '.
     305      '(`time` < "'.TimeToMysqlDateTime($TimeTo).'") AND '.
     306      '(`measure`='.$this->Data['Id'].') AND (`level`='.$Level.') ORDER BY `time`');
     307    $Values = array();
     308    while($Row = $Result->fetch_array())
     309    {
     310      $Values[] = array('time' => MysqlDateTimeToTime($Row['time']), 'min' => $Row['min'], 'avg' => $Row['avg'], 'max' => $Row['max'], 'continuity' => $Row['continuity']);
     311    }
     312   // array_pop($Values);
     313
    314314    $Points = array();
    315     for($I = 0; $I < $DivisionCount; $I++)
    316     {
    317       $TimeStart = $TimeFrom + (($TimeTo - $TimeFrom) / $DivisionCount) * $I;
    318       //if($Debug) echo('TimeStart '.$I.': '.$TimeStart.'('.TimeToMysqlDateTime($TimeStart).')<br>');
    319       $TimeEnd = $TimeFrom + (($TimeTo - $TimeFrom) / $DivisionCount) * ($I+1);
    320       //if($Debug) echo('TimeEnd '.$I.': '.$TimeEnd.'('.TimeToMysqlDateTime($TimeEnd).')<br>');
    321 
    322       $EndIndex = $StartIndex;
    323       while($Values[$EndIndex]['time'] < $TimeEnd) $EndIndex = $EndIndex + 1;
    324       $SubValues = array_slice($Values, $StartIndex, $EndIndex - $StartIndex + 1);
    325       $Points[] = ComputeOneValue($TimeStart, $TimeEnd, $SubValues, $Measure, $Level);
    326       $StartIndex = $EndIndex - 1; 
    327     }
    328   } else $Points[] = array('min' => 0, 'avg' => 0, 'max' => 0);
    329   return($Points);
    330 }
    331 
    332 function RebuildMeasureCache($Measure)
    333 {
    334   global $MaxLevel, $LevelReducing, $Database;
    335 
    336   echo('Velicina '.$Measure['Name']."<br>\n");
    337   if($Measure['Continuity'] == 0) $Measure['ContinuityEnabled'] = 0;  // non continuous
    338     else $Measure['ContinuityEnabled'] = 2;    // continuous graph
    339 
    340   // Clear previous items
    341   $DbResult = $Database->select($Measure['DataTable'], 'COUNT(*)', 'level>0 AND measure='.$Measure['Id']);
    342   $Row = $DbResult->fetch_array();
    343   echo("Mazu starou cache (".$Row[0]." polozek)...");
    344   $Database->delete($Measure['DataTable'], 'level>0 AND measure='.$Measure['Id']);
    345   echo("<br>\n");
    346 
    347   for($Level=1; $Level <= $MaxLevel; $Level++)
    348   {
    349     echo('Uroven '.$Level."<br>\n");
    350     $TimeRange = GetTimeRange($Measure, $Level-1);
    351     $TimeSegment = TimeSegment($Level);
    352     $StartTime = AlignTime($TimeRange['left'], $TimeSegment) - $TimeSegment;
    353     $EndTime = AlignTime($TimeRange['right'], $TimeSegment);
    354     $BurstCount = 500;
    355     echo('For 0 to '.round(($EndTime - $StartTime) / $TimeSegment / $BurstCount)."<br>\n");
    356     for($I = 0; $I <= round(($EndTime - $StartTime) / $TimeSegment / $BurstCount); $I++)
    357     {
    358       echo($I.' ');
    359       $StartTime2 = $StartTime + $I * $BurstCount * $TimeSegment;
    360       $EndTime2 = $StartTime + ($I + 1) * $BurstCount * $TimeSegment;
    361       $Values = array();
    362       $DbResult = $Database->select($Measure['DataTable'], '*', '(time > "'.TimeToMysqlDateTime($StartTime2).'") AND (time < "'.
    363         TimeToMysqlDateTime($EndTime2).'") AND (measure='.$Measure['Id'].') AND (level='.($Level - 1).') ORDER BY time');
    364       while($Row = $DbResult->fetch_array())
    365       {
    366         $Row['time'] = MysqlDateTimeToTime($Row['time']);
    367         $Values[] = $Row;
    368       }
    369 
    370       if(count($Values) > 0)
    371       {
    372         $Values = array_merge(LoadLeftSideValue($Level - 1, $Measure, $StartTime2), $Values, LoadRightSideValue($Level - 1, $Measure, $EndTime2));
    373 
    374         $StartIndex = 0;
    375         for($B = 0; $B < $BurstCount; $B++)
    376         {
    377           echo('.');
    378           $StartTime3 = $StartTime2 + (($EndTime2 - $StartTime2) / $BurstCount) * $B;
    379           $EndTime3 = $StartTime2 + (($EndTime2 - $StartTime2) / $BurstCount) * ($B + 1);
    380 
    381           $EndIndex = $StartIndex;
    382           while($Values[$EndIndex]['time'] < $EndTime3) $EndIndex = $EndIndex + 1;
    383           $SubValues = array_slice($Values, $StartIndex, $EndIndex - $StartIndex + 1);
    384          if(count($SubValues) > 2)
     315    if(count($Values) > 0)
     316    {
     317      $Values = array_merge(
     318        $this->LoadLeftSideValue($Level, $TimeFrom),
     319        $Values,
     320        $this->LoadRightSideValue($Level, $TimeTo));
     321
     322      $StartIndex = 0;
     323      $Points = array();
     324      for($I = 0; $I < $this->DivisionCount; $I++)
     325      {
     326        $TimeStart = $TimeFrom + (($TimeTo - $TimeFrom) / $this->DivisionCount) * $I;
     327        $TimeEnd = $TimeFrom + (($TimeTo - $TimeFrom) / $this->DivisionCount) * ($I+1);
     328
     329        $EndIndex = $StartIndex;
     330        while($Values[$EndIndex]['time'] < $TimeEnd) $EndIndex = $EndIndex + 1;
     331        $SubValues = array_slice($Values, $StartIndex, $EndIndex - $StartIndex + 1);
     332        $Points[] = $this->ComputeOneValue($TimeStart, $TimeEnd, $SubValues, $Level);
     333        $StartIndex = $EndIndex - 1;
     334      }
     335    } else $Points[] = array('min' => 0, 'avg' => 0, 'max' => 0);
     336    return($Points);
     337  }
     338
     339  function RebuildMeasureCache()
     340  {
     341    echo('Velicina '.$this->Data['Name']."<br>\n");
     342    if($this->Data['Continuity'] == 0) $this->Data['ContinuityEnabled'] = 0;  // non continuous
     343      else $this->Data['ContinuityEnabled'] = 2;    // continuous graph
     344
     345    // Clear previous items
     346    $DbResult = $this->Database->select($this->Data['DataTable'], 'COUNT(*)', '(`level`>0) AND (`measure`='.$this->Data['Id'].')');
     347    $Row = $DbResult->fetch_array();
     348    echo("Mazu starou cache (".$Row[0]." polozek)...");
     349    $this->Database->delete($this->Data['DataTable'], '(`level`>0) AND (`measure`='.$this->Data['Id'].')');
     350    echo("<br>\n");
     351
     352    for($Level = 1; $Level <= $this->MaxLevel; $Level++)
     353    {
     354      echo('Uroven '.$Level."<br>\n");
     355      $TimeRange = $this->GetTimeRange($Level - 1);
     356      $TimeSegment = $this->TimeSegment($Level);
     357      $StartTime = $this->AlignTime($TimeRange['left'], $TimeSegment) - $TimeSegment;
     358      $EndTime = $this->AlignTime($TimeRange['right'], $TimeSegment);
     359      $BurstCount = 500;
     360      echo('For 0 to '.round(($EndTime - $StartTime) / $TimeSegment / $BurstCount)."<br>\n");
     361      for($I = 0; $I <= round(($EndTime - $StartTime) / $TimeSegment / $BurstCount); $I++)
     362      {
     363        echo($I.' ');
     364        $StartTime2 = $StartTime + $I * $BurstCount * $TimeSegment;
     365        $EndTime2 = $StartTime + ($I + 1) * $BurstCount * $TimeSegment;
     366        $Values = array();
     367        $DbResult = $this->Database->select($this->Data['DataTable'], '*', '(`time` > "'.TimeToMysqlDateTime($StartTime2).'") AND (`time` < "'.
     368          TimeToMysqlDateTime($EndTime2).'") AND (`measure`='.$this->Data['Id'].') AND (`level`='.($Level - 1).') ORDER BY `time`');
     369        while($Row = $DbResult->fetch_array())
     370        {
     371          $Row['time'] = MysqlDateTimeToTime($Row['time']);
     372          $Values[] = $Row;
     373        }
     374
     375        if(count($Values) > 0)
     376        {
     377          $Values = array_merge(
     378            $this->LoadLeftSideValue($Level - 1, $StartTime2),
     379            $Values,
     380            $this->LoadRightSideValue($Level - 1, $EndTime2));
     381
     382          $StartIndex = 0;
     383          for($B = 0; $B < $BurstCount; $B++)
    385384          {
    386             $Point = ComputeOneValue($StartTime3, $EndTime3, $SubValues, $Measure, $Level);
    387             $Continuity = $SubValues[1]['continuity'];
    388             $Database->insert($Measure['DataTable'], array('level' => $Level, 'measure' => $Measure['Id'],
    389               'min' => $Point['min'], 'avg' => $Point['avg'], 'max' => $Point['max'],
    390               'continuity' => $Continuity, 'time' => TimeToMysqlDateTime($StartTime3 + ($EndTime3 - $StartTime3) / 2)));
     385            echo('.');
     386            $StartTime3 = $StartTime2 + (($EndTime2 - $StartTime2) / $BurstCount) * $B;
     387            $EndTime3 = $StartTime2 + (($EndTime2 - $StartTime2) / $BurstCount) * ($B + 1);
     388
     389            $EndIndex = $StartIndex;
     390            while($Values[$EndIndex]['time'] < $EndTime3) $EndIndex = $EndIndex + 1;
     391            $SubValues = array_slice($Values, $StartIndex, $EndIndex - $StartIndex + 1);
     392            if(count($SubValues) > 2)
     393            {
     394              $Point = $this->ComputeOneValue($StartTime3, $EndTime3, $SubValues, $Level);
     395              $Continuity = $SubValues[1]['continuity'];
     396              $this->Database->insert($this->Data['DataTable'], array('level' => $Level, 'measure' => $this->Data['Id'],
     397                'min' => $Point['min'], 'avg' => $Point['avg'], 'max' => $Point['max'],
     398                'continuity' => $Continuity, 'time' => TimeToMysqlDateTime($StartTime3 + ($EndTime3 - $StartTime3) / 2)));
     399            }
     400            $StartIndex = $EndIndex - 1;
    391401          }
    392           $StartIndex = $EndIndex - 1;
    393         }
    394       }
    395       // Load values in time range
    396       //array_pop($NextValues);
    397     }
    398     echo("Uroven dokoncena<br>\n");
    399     $DbResult = $Database->select($Measure['DataTable'], 'COUNT(*)', 'level='.$Level.' AND measure='.$Measure['Id']);
    400     $Row = $DbResult->fetch_array();
    401     echo("Vlozeno ".$Row[0]." polozek.<br>\n");
    402   }
    403 }
    404 
    405 function RebuildAllMeasuresCache()
    406 {
    407   global $Database;
    408 
    409   // Load measures
    410   $Measures = array();
    411   $Result = $Database->select('measure', '*');
    412   while($Measures[] = $Result->fetch_array());
    413     array_pop($Measures);
    414 
    415   foreach($Measures as $Measure)
    416   {
    417     RebuildMeasureCache($Measure);
    418     echo('Velicina dokoncena<br/>');
    419   }
    420 }
    421 
    422 function InitMeasureDataTable($Measure)
    423 {
    424   global $Database;
    425 
    426   $Database->query('CREATE TABLE `data_'.$Measure['Name'].'` (
     402        }
     403        // Load values in time range
     404        //array_pop($NextValues);
     405      }
     406      echo("Uroven dokoncena<br>\n");
     407      $DbResult = $this->Database->select($this->Data['DataTable'], 'COUNT(*)',
     408        '(`level`='.$Level.') AND (`measure`='.$this->Data['Id'].')');
     409      $Row = $DbResult->fetch_array();
     410      echo("Vlozeno ".$Row[0]." polozek.<br>\n");
     411    }
     412  }
     413
     414  function RebuildAllMeasuresCache()
     415  {
     416    $Result = $this->Database->select('measure', 'Id');
     417    while($Row = $Result->fetch_array())
     418    {
     419      $Measure = new Measure();
     420      $Measure->Load($Row['Id']);
     421      $Measure->RebuildMeasureCache();
     422      echo('Velicina id '.$Row['Id'].' dokoncena<br/>');
     423    }
     424  }
     425
     426  function InitMeasureDataTable()
     427  {
     428    $this->Database->query('CREATE TABLE `data_'.$this->Data['Name'].'` (
     429      `Time` TIMESTAMP NOT NULL ,
     430      `Avg` '.$this->Data['DataType'].' NOT NULL ,
     431      `Continuity` BOOL NOT NULL
     432      ) ENGINE = MYISAM ;');
     433
     434    $this->Database->query('CREATE TABLE `data_'.$this->Data['Name'].'_cache` (
    427435`Time` TIMESTAMP NOT NULL ,
    428 `Avg` '.$Measure['DataType'].' NOT NULL ,
     436`Level` TINYINT NOT NULL ,
     437`Min` '.$this->Data['DataType'].' NOT NULL ,
     438`Avg` '.$this->Data['DataType'].' NOT NULL ,
     439`Max` '.$this->Data['DataType'].' NOT NULL ,
    429440`Continuity` BOOL NOT NULL
    430441) ENGINE = MYISAM ;');
    431 
    432   $Database->query('CREATE TABLE `data_'.$Measure['Name'].'_cache` (
    433 `Time` TIMESTAMP NOT NULL ,
    434 `Level` TINYINT NOT NULL ,
    435 `Min` '.$Measure['DataType'].' NOT NULL ,
    436 `Avg` '.$Measure['DataType'].' NOT NULL ,
    437 `Max` '.$Measure['DataType'].' NOT NULL ,
    438 `Continuity` BOOL NOT NULL
    439 ) ENGINE = MYISAM ;');
     442  }
    440443}
Note: See TracChangeset for help on using the changeset viewer.