3
class DATAPoint implements Iterator {
12
var $ikey, $irow, $nextikey, $nextirow;
16
var $gaps; // Indicates if there gaps on the graph
17
var $missing; // Information on the data missing in the database
21
var $state; // Type of previous step (0 - 'min' value is taken, 1 - 'max' value is taken)
22
var $nextivl; // Indicates if we should read next interval
23
var $empty_key; // Cursor for reporting empty intervals
31
var $expected_gap; // Expected distance between points
32
var $allowed_gap; // Do not report gaps bellow this threshold
34
function __construct(CACHEDB &$cache, MASK &$mask, INTERVAL &$ivl, $type, $amount, $limit, $resolution, $flags = 0) {
35
$this->cache = &$cache;
36
$this->ids = sizeof($mask->ids);
41
$this->limit = $limit;
42
$this->amount = $amount;
44
if ($resolution === false) $this->resolution = $cache->resolution->Get($this->ivl, $this->amount);
45
else $this->resolution = $resolution;
47
$this->operation_info = array();
49
$this->options = array();
51
$this->flags = $flags;
53
$resolution = $cache->resolution->GetWindowSize($this->resolution);
55
$size = $ivl->GetWindowSize();
57
$mingap = $size / $limit;
59
$mingap = ceil($mingap / $resolution)*$resolution;
61
} else if ($resolution) {
62
$mingap = $resolution;
67
$this->expected_gap = $mingap;
70
if (($this->flags&CACHE::REPORT_EMPTY)||($this->flags&CACHE::MISSING_INFO)) {
71
$res = $cache->resolution->Minimal();
72
$this->allowed_gap = $cache->resolution->GetWindowSize($res);
76
echo $amount . " , " . $limit . "\n";
82
function SetOption($option, $value = false) {
85
$this->$option = $value;
88
$this->options[$option] = $value;
92
function SetOptions($options) {
93
$this->options = array_merge($this->options, $option);
97
function MINMAXFirst(&$key, &$ivl) {
99
for ($i=0;$i<$this->ids;$i++) {
100
$this->row[$i] = $ivl['min' . $i];
101
$this->state[$i] = 0;
104
if (($this->allowed_gap)&&($ivl['maxgap'] > $this->allowed_gap))
105
$this->missing = $ivl['maxgap'];
109
$this->started = true;
112
function MINMAXLast(&$key, &$ivl) {
113
$this->started = false;
116
for ($i=0;$i<$this->ids;$i++) {
117
if ($this->state[$i]) {
118
$this->row[$i] = $ivl['min' . $i];
120
$this->row[$i] = $ivl['max' . $i];
127
function MINMAXStep(&$key1, &$ivl1, &$key2, &$ivl2) {
130
for ($i=0;$i<$this->ids;$i++) {
131
if ($this->state[$i]) {
132
if ($ivl2['max' . $i] > $ivl1['min' . $i]) {
133
if (($key1)&&($ivl1['min' . $i] < $ivl2['min' . $i])) $votes++;
135
$this->row[$i] = min($ivl1['min' . $i], $ivl2['min' . $i]);
136
$this->state[$i] = 0;
138
$this->row[$i] = $ivl2['max' . $i];
141
if ($ivl2['min' . $i] < $ivl1['max' . $i]) {
142
if (($key1)&&($ivl1['max' . $i] > $ivl2['max' . $i])) $votes++;
144
$this->row[$i] = max($ivl1['max' . $i], $ivl2['max' . $i]);
145
$this->state[$i] = 1;
147
$this->row[$i] = $ivl2['min' . $i];
151
if ($votes * 2 > $this->ids)
157
if (($this->allowed_gap)&&($ivl2['maxgap'] > $this->allowed_gap))
158
$this->missing = $ivl2['maxgap'];
164
function GetPoint(&$key1, &$ivl1, &$key2, &$ivl2) {
165
$this->row = array();
167
switch ($this->type) {
168
case CACHE::TYPE_MEAN:
169
if ($this->empty_key) {
170
$nextkey = dsMathPreciseAdd($this->empty_key, $this->expected_gap);
171
if ($nextkey > $key1) {
172
$this->empty_key = false;
174
$this->key = $this->empty_key;
175
$this->row[0] = false;
176
$this->empty_key = $nextkey;
185
if (($ivl2)&&(($this->flags&CACHE::REPORT_EMPTY)||($this->flags&CACHE::MISSING_INFO))) {
186
$key1end = dsMathPreciseAdd($key1, $ivl1['width']);
187
$distance = dsMathPreciseSubstract($key2, $key1end);
189
if (($this->allowed_gap)&&($distance > $this->allowed_gap)) {
190
$this->missing = $distance;
192
if ($distance > 2 * $this->expected_gap) {
195
if ($this->flags&CACHE::REPORT_EMPTY) {
196
$this->empty_key = dsMathPreciseAdd($key1end, $this->expected_gap);
204
$this->key = dsMathPreciseAdd($key1, $ivl['width']/2);
209
$this->key = dsMathPreciseAdd($key2, $ivl['width']/2);
212
if (($this->allowed_gap)&&(!$this->missing)&&($ivl['maxgap'] > $this->allowed_gap))
213
$this->missing = $ivl['maxgap'];
216
for ($i=0;$i<$this->ids;$i++)
217
$this->row[$i] = $ivl['mean' . $i];
219
case CACHE::TYPE_MINMAX:
220
if ($this->started) {
221
$key1end = dsMathPreciseAdd($key1, $ivl1['width']);
224
$distance = dsMathPreciseSubstract($key2, $key1end);
225
if ($distance > 2 * $this->expected_gap) {
226
$this->MINMAXLast($key1end, $ivl1);
228
if (($this->allowed_gap)&&($distance > $this->allowed_gap)) {
229
$this->missing = $distance;
233
if ($this->flags&CACHE::REPORT_EMPTY) {
234
$this->empty_key = dsMathPreciseAdd($key1end, $this->expected_gap);
242
$this->MINMAXStep($key1end, $ivl1, $key2, $ivl2);
244
$this->MINMAXStep($key1end=false, $ivl1, $key2, $ivl2);
246
$this->MINMAXLast($key1end, $ivl1);
249
if ($this->empty_key) {
250
$nextkey = dsMathPreciseAdd($this->empty_key, $this->expected_gap);
251
if ($nextkey > $key2) {
252
$this->empty_key = false;
254
$this->key = $this->empty_key;
255
$this->row[0] = false;
256
$this->empty_key = $nextkey;
260
} else if (($ivl1)&&($this->allowed_gap)) {
261
$key1end = dsMathPreciseAdd($key1, $ivl1['width']);
262
$distance = dsMathPreciseSubstract($key2, $key1end);
264
if ($distance > $this->allowed_gap) {
266
if ($this->flags&CACHE::REPORT_EMPTY) {
267
$this->empty_key = dsMathPreciseAdd($key1end, $this->expected_gap);
273
if (!$ivl2['width']) {
275
for ($i=0;$i<$this->ids;$i++) {
276
$this->row[$i] = $ivl2['min' . $i];
280
if (($this->flags&CACHE::MISSING_INFO)&&($this->allowed_gap)) {
281
if (($this->interval)&&($this->interval->valid())) {
282
$this->row3 = $this->interval->current();
283
$this->key3 = $this->interval->key();
284
$this->interval->next();
286
$distance = dsMathPreciseSubstract($key3, $key2);
287
if ($distance->allowed_gap) $this->missing = $distance;
292
$this->MINMAXFirst($key2, $ivl2);
295
/* if not started and no ivl2 - we are done */
300
throw new ADEIException(translate("Invalid interval aggregation mode (%u) is specified", $this->type));
308
$this->interval = new DATAInterval($this->cache, $this->mask, $this->ivl, $this->amount, $this->limit?($this->limit + 1):0, $this->resolution, CACHE::TRUNCATE_INTERVALS|(($this->flags&CACHE::MISSING_INFO)?CACHE::MISSING_INFO:0));
309
if (sizeof($this->options) > 0) $this->interval->SetOptions($this->options);
311
$this->started = false;
312
$this->nextivl = true;
313
$this->empty_key = false;
315
$this->nextkey = false;
316
$this->nextrow = false;
323
$this->interval->rewind();
328
if ($this->row[0] === false)
338
function missing_data() {
339
return $this->missing;
342
function missing_points() {
347
if ($this->nextivl) {
348
$this->irow = $this->nextirow;
349
$this->ikey = $this->nextikey;
352
$this->nextirow = $this->row3;
353
$this->nextikey = $this->key3;
357
} elseif ($this->interval) {
358
if ($this->interval->valid()) {
359
$this->nextirow = $this->interval->current();
360
$this->nextikey = $this->interval->key();
361
$this->interval->next();
363
$this->nextirow = false;
364
$this->nextikey = false;
365
$this->operation_info = $this->interval->GetOperationInfo();
366
unset($this->interval);
371
$this->nextivl = $this->GetPoint($this->ikey, $this->irow, $this->nextikey, $this->nextirow);
375
return ($this->interval||$this->irow)?true:false;
378
function GetOperationInfo() {
379
if ($this->interval) $ivlinfo = $this->interval->GetOperationInfo();
380
else $ivlinfo = $this->operation_info;
382
$ivlinfo['aggregation'] = $this->type;
b'\\ No newline at end of file'