/dev/trunk

To get this branch, use:
bzr branch http://darksoft.org/webbzr/dev/trunk

« back to all changes in this revision

Viewing changes to classes/cache/datapoint.php

  • Committer: Suren A. Chilingaryan
  • Date: 2008-04-02 10:23:22 UTC
  • Revision ID: csa@dside.dyndns.org-20080402102322-okib92sicg2dx3o3
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
class DATAPoint implements Iterator {
 
4
 var $cache;
 
5
 var $mask, $ids;
 
6
 var $ivl;
 
7
 var $type;
 
8
 
 
9
 var $limit, $amount;
 
10
 
 
11
 var $interval;
 
12
 var $ikey, $irow, $nextikey, $nextirow;
 
13
 var $key3, $row3;
 
14
 
 
15
 var $key, $row;
 
16
 var $gaps;             // Indicates if there gaps on the graph
 
17
 var $missing;          // Information on the data missing in the database
 
18
 
 
19
    // MINMAX specific
 
20
 var $started;
 
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
 
24
 
 
25
 var $operation_info;
 
26
 
 
27
 var $options;
 
28
 
 
29
 var $flags;
 
30
 
 
31
 var $expected_gap;     // Expected distance between points
 
32
 var $allowed_gap;      // Do not report gaps bellow this threshold
 
33
   
 
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);
 
37
    $this->ivl = &$ivl;
 
38
    $this->mask = &$mask;
 
39
    
 
40
    $this->type = $type;
 
41
    $this->limit = $limit;
 
42
    $this->amount = $amount;
 
43
 
 
44
    if ($resolution === false) $this->resolution = $cache->resolution->Get($this->ivl, $this->amount);
 
45
    else $this->resolution = $resolution;
 
46
    
 
47
    $this->operation_info = array();
 
48
    
 
49
    $this->options = array();
 
50
    
 
51
    $this->flags = $flags;
 
52
    
 
53
    $resolution = $cache->resolution->GetWindowSize($this->resolution);
 
54
 
 
55
    $size = $ivl->GetWindowSize();
 
56
    if ($limit) {
 
57
        $mingap = $size / $limit;
 
58
        if ($resolution) {
 
59
            $mingap = ceil($mingap / $resolution)*$resolution;
 
60
        }
 
61
    } else if ($resolution) {
 
62
        $mingap = $resolution;
 
63
    } else {
 
64
        $mingap = 0;
 
65
    }
 
66
 
 
67
    $this->expected_gap = $mingap;
 
68
    
 
69
 
 
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);
 
73
    }
 
74
 
 
75
/*    
 
76
    echo $amount . " , " . $limit . "\n";
 
77
    echo $mingap . "\n";
 
78
    exit;
 
79
*/
 
80
 }
 
81
 
 
82
 function SetOption($option, $value = false) {
 
83
    switch ($option) {
 
84
        case "allowed_gap":
 
85
            $this->$option = $value;
 
86
        break;
 
87
        default:
 
88
            $this->options[$option] = $value;
 
89
    }
 
90
 } 
 
91
 
 
92
 function SetOptions($options) {
 
93
    $this->options = array_merge($this->options, $option);
 
94
 }
 
95
 
 
96
 
 
97
 function MINMAXFirst(&$key, &$ivl) {
 
98
    $this->key = $key;
 
99
    for ($i=0;$i<$this->ids;$i++) {
 
100
        $this->row[$i] = $ivl['min' . $i];
 
101
        $this->state[$i] = 0;
 
102
    }
 
103
 
 
104
    if (($this->allowed_gap)&&($ivl['maxgap'] > $this->allowed_gap))
 
105
        $this->missing = $ivl['maxgap'];
 
106
    else
 
107
        $this->missing = 0;
 
108
    
 
109
    $this->started = true;
 
110
 }
 
111
 
 
112
 function MINMAXLast(&$key, &$ivl) {
 
113
    $this->started = false;
 
114
 
 
115
    $this->key = $key;
 
116
    for ($i=0;$i<$this->ids;$i++) {
 
117
        if ($this->state[$i]) {
 
118
            $this->row[$i] = $ivl['min' . $i];
 
119
        } else {
 
120
            $this->row[$i] = $ivl['max' . $i];
 
121
        }
 
122
    }
 
123
    
 
124
    $this->missing = 0;
 
125
 }
 
126
 
 
127
 function MINMAXStep(&$key1, &$ivl1, &$key2, &$ivl2) {
 
128
    $votes = 0;
 
129
    
 
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++;
 
134
 
 
135
                $this->row[$i] = min($ivl1['min' . $i], $ivl2['min' . $i]);
 
136
                $this->state[$i] = 0;
 
137
            } else {
 
138
                $this->row[$i] =  $ivl2['max' . $i];
 
139
            }
 
140
        } else {
 
141
            if ($ivl2['min' . $i] < $ivl1['max' . $i]) {
 
142
                if (($key1)&&($ivl1['max' . $i] > $ivl2['max' . $i])) $votes++;
 
143
                
 
144
                $this->row[$i] = max($ivl1['max' . $i], $ivl2['max' . $i]);
 
145
                $this->state[$i] = 1;
 
146
            } else {
 
147
                $this->row[$i] =  $ivl2['min' . $i];
 
148
            }
 
149
        }
 
150
    }
 
151
    if ($votes * 2 > $this->ids) 
 
152
        $this->key = $key1;
 
153
    else
 
154
        $this->key = $key2;
 
155
 
 
156
 
 
157
    if (($this->allowed_gap)&&($ivl2['maxgap'] > $this->allowed_gap))
 
158
        $this->missing = $ivl2['maxgap'];
 
159
    else
 
160
        $this->missing = 0;
 
161
 
 
162
 }
 
163
 
 
164
 function GetPoint(&$key1, &$ivl1, &$key2, &$ivl2) {
 
165
    $this->row = array();
 
166
 
 
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;
 
173
                } else {
 
174
                    $this->key = $this->empty_key;
 
175
                    $this->row[0] = false;
 
176
                    $this->empty_key = $nextkey;
 
177
 
 
178
                    return false;
 
179
                }
 
180
            }
 
181
            
 
182
            $this->missing = 0;
 
183
 
 
184
            if ($ivl1) {
 
185
                if (($ivl2)&&(($this->flags&CACHE::REPORT_EMPTY)||($this->flags&CACHE::MISSING_INFO))) {
 
186
                    $key1end = dsMathPreciseAdd($key1, $ivl1['width']);
 
187
                    $distance = dsMathPreciseSubstract($key2, $key1end);
 
188
                    
 
189
                    if (($this->allowed_gap)&&($distance > $this->allowed_gap)) {
 
190
                        $this->missing = $distance;
 
191
                        
 
192
                        if ($distance > 2 * $this->expected_gap) {
 
193
                            $this->gaps = true;
 
194
                        
 
195
                            if ($this->flags&CACHE::REPORT_EMPTY) {
 
196
                                $this->empty_key = dsMathPreciseAdd($key1end, $this->expected_gap);
 
197
                            }
 
198
                        }
 
199
                    }
 
200
                }
 
201
 
 
202
                $ivl = &$ivl1;
 
203
 
 
204
                $this->key = dsMathPreciseAdd($key1, $ivl['width']/2);
 
205
            } else {
 
206
                $ivl = &$ivl2;
 
207
                
 
208
                
 
209
                $this->key = dsMathPreciseAdd($key2, $ivl['width']/2);
 
210
            } 
 
211
 
 
212
            if (($this->allowed_gap)&&(!$this->missing)&&($ivl['maxgap'] > $this->allowed_gap))
 
213
                $this->missing = $ivl['maxgap'];
 
214
 
 
215
            
 
216
            for ($i=0;$i<$this->ids;$i++)
 
217
                $this->row[$i] = $ivl['mean' . $i];
 
218
         break;
 
219
         case CACHE::TYPE_MINMAX:
 
220
            if ($this->started) {
 
221
                $key1end = dsMathPreciseAdd($key1, $ivl1['width']);
 
222
 
 
223
                if ($ivl2) {
 
224
                    $distance = dsMathPreciseSubstract($key2, $key1end);
 
225
                    if ($distance > 2 * $this->expected_gap) {
 
226
                        $this->MINMAXLast($key1end, $ivl1);
 
227
                            
 
228
                        if (($this->allowed_gap)&&($distance > $this->allowed_gap)) {
 
229
                            $this->missing = $distance;
 
230
 
 
231
                            $this->gaps = true;
 
232
 
 
233
                            if ($this->flags&CACHE::REPORT_EMPTY) {
 
234
                                $this->empty_key = dsMathPreciseAdd($key1end, $this->expected_gap);
 
235
                            }
 
236
                        }
 
237
                        
 
238
                        return false;
 
239
                    }
 
240
                    
 
241
                    if ($distance>0)
 
242
                        $this->MINMAXStep($key1end, $ivl1, $key2, $ivl2);
 
243
                    else
 
244
                        $this->MINMAXStep($key1end=false, $ivl1, $key2, $ivl2);
 
245
                } else if ($ivl1) {
 
246
                    $this->MINMAXLast($key1end, $ivl1);
 
247
                }
 
248
            } else if ($ivl2) {
 
249
                if ($this->empty_key) {
 
250
                    $nextkey = dsMathPreciseAdd($this->empty_key, $this->expected_gap);
 
251
                    if ($nextkey > $key2) {
 
252
                        $this->empty_key = false;
 
253
                    } else {
 
254
                        $this->key = $this->empty_key;
 
255
                        $this->row[0] = false;
 
256
                        $this->empty_key = $nextkey;
 
257
 
 
258
                        return false;
 
259
                    }
 
260
                } else if (($ivl1)&&($this->allowed_gap)) {
 
261
                    $key1end = dsMathPreciseAdd($key1, $ivl1['width']);
 
262
                    $distance = dsMathPreciseSubstract($key2, $key1end);
 
263
                    
 
264
                    if ($distance > $this->allowed_gap) {
 
265
                        $this->gaps = true;
 
266
                        if ($this->flags&CACHE::REPORT_EMPTY) {
 
267
                            $this->empty_key = dsMathPreciseAdd($key1end, $this->expected_gap);
 
268
                            return false;
 
269
                        }
 
270
                    }
 
271
                }
 
272
                
 
273
                if (!$ivl2['width']) {
 
274
                    $this->key = $key2;
 
275
                    for ($i=0;$i<$this->ids;$i++) {
 
276
                        $this->row[$i] = $ivl2['min' . $i];
 
277
                    }
 
278
            
 
279
                    $this->missing = 0;
 
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();
 
285
                            
 
286
                            $distance = dsMathPreciseSubstract($key3, $key2);
 
287
                            if ($distance->allowed_gap) $this->missing = $distance;
 
288
                        }
 
289
 
 
290
                    }
 
291
                } else {
 
292
                    $this->MINMAXFirst($key2, $ivl2);
 
293
                }
 
294
            } else {
 
295
                 /* if not started and no ivl2 - we are done */
 
296
                 unset($this->irow);
 
297
            }
 
298
        break;
 
299
         default:
 
300
            throw new ADEIException(translate("Invalid interval aggregation mode (%u) is specified", $this->type));
 
301
    }
 
302
    return true;
 
303
 
 
304
//    print_r($ivl1);
 
305
 }
 
306
 
 
307
 function rewind() {
 
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);
 
310
 
 
311
    $this->started = false;
 
312
    $this->nextivl = true;
 
313
    $this->empty_key = false;
 
314
    
 
315
    $this->nextkey = false;
 
316
    $this->nextrow = false;
 
317
    
 
318
    $this->row3 = false;
 
319
    $this->key3 = false;
 
320
    
 
321
    $this->gaps = false;
 
322
    
 
323
    $this->interval->rewind();
 
324
    $this->next();
 
325
 }
 
326
 
 
327
 function current() {
 
328
    if ($this->row[0] === false) 
 
329
        return false;
 
330
        
 
331
    return $this->row;
 
332
 }
 
333
 
 
334
 function key() {
 
335
    return $this->key;
 
336
 }
 
337
 
 
338
 function missing_data() {
 
339
    return $this->missing;
 
340
 }
 
341
 
 
342
 function missing_points() {
 
343
    return $this->gaps;
 
344
 }
 
345
 
 
346
 function next() {
 
347
    if ($this->nextivl) {
 
348
        $this->irow = $this->nextirow;
 
349
        $this->ikey = $this->nextikey;
 
350
    
 
351
        if ($this->key3) {
 
352
            $this->nextirow = $this->row3;
 
353
            $this->nextikey = $this->key3;
 
354
            
 
355
            $this->key3 = false;
 
356
            $this->row3 = false;
 
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();
 
362
            } else {
 
363
                $this->nextirow = false;
 
364
                $this->nextikey = false;
 
365
                $this->operation_info = $this->interval->GetOperationInfo();
 
366
                unset($this->interval);
 
367
            }
 
368
        }
 
369
    }
 
370
 
 
371
    $this->nextivl = $this->GetPoint($this->ikey, $this->irow, $this->nextikey, $this->nextirow);
 
372
 }
 
373
 
 
374
 function valid() {
 
375
    return ($this->interval||$this->irow)?true:false;
 
376
 }
 
377
 
 
378
 function GetOperationInfo() {
 
379
    if ($this->interval) $ivlinfo = $this->interval->GetOperationInfo();
 
380
    else $ivlinfo = $this->operation_info;
 
381
    
 
382
    $ivlinfo['aggregation'] = $this->type;
 
383
 
 
384
    return $ivlinfo;
 
385
 }
 
386
}
 
387
 
 
388
 
 
389
?>
 
 
b'\\ No newline at end of file'