]> pilppa.org Git - libplp.git/blob - src/DataReader.cc
Data read optimizations
[libplp.git] / src / DataReader.cc
1 /*
2  * DataReader.cc
3  *
4  *  Created on: Nov 7, 2010
5  *      Author: lamikr
6  */
7 #include <sstream>
8
9 #include <dirent.h>
10 #include <malloc.h>
11 #include <errno.h>
12 #include <string.h>
13
14 #include "log.h"
15
16 #include "DataReader.hh"
17 #include "DeviceConfig.hh"
18 #include "FileUtil.hh"
19 #include "StoreDay.hh"
20 #include "StoreCache.hh"
21
22 using namespace std;
23 using namespace plp;
24
25 template <class NumberDataType>
26 bool string_to_number(NumberDataType& result,
27                  const std::string& string_param,
28                  std::ios_base& (*format)(std::ios_base&))
29 {
30         istringstream iss(string_param);
31         return !(iss >> format >> result).fail();
32 }
33
34 DataReader::DataReader(string device_id_param) {
35         string  base_dir;
36
37         log_debug("device_id: %s\n", device_id_param.c_str());
38         summary_calc_type       = MEAN;
39         device_config           = NULL;
40         device_id               = device_id_param;
41         base_dir                = DeviceConfig::get_base_dir_name();
42         device_dir              = FileUtil::concat_paths(base_dir, device_id);
43         device_ch_dir           = FileUtil::concat_paths(base_dir, "cache");
44         device_ch_dir           = FileUtil::concat_paths(device_ch_dir, device_id);
45 }
46
47 DataReader::~DataReader() {
48         if (device_config != NULL) {
49                 delete(device_config);
50                 device_config   = NULL;
51         }
52 }
53
54 Data *DataReader::find_latest_data(vector<string> year_name_vector_param) {
55         string  year_name;
56         int     size;
57         Data    *ret_val;
58         Date    date;
59         int     val_int;
60
61         ret_val = NULL;
62         size    = year_name_vector_param.size();
63         if (size > 0) {
64                 // dirs are alphabetically sorted
65                 year_name       = year_name_vector_param.at(size - 1);
66                 string_to_number<int>(val_int, year_name, dec);
67                 date.year       = val_int;
68                 ret_val         = StoreCache::get_latest_data(&date, device_id, PERIOD_YEARLY);
69         }
70         return ret_val;
71 }
72
73 Data *DataReader::get_latest_data() {
74         vector<string>  y_list;
75         Data            *ret_val;
76
77         ret_val = NULL;
78         y_list  = FileUtil::get_subdirectories(device_dir);
79         if (y_list.size() > 0) {
80                 ret_val = find_latest_data(y_list);
81         }
82         return ret_val;
83 }
84
85 Data *DataReader::find_oldest_data(vector<string> year_name_vector_param) {
86         int     size;
87         string  year_name;
88         Data    *ret_val;
89         Date    date;
90         int     val_int;
91
92         ret_val = NULL;
93         size    = year_name_vector_param.size();
94         if (size > 0) {
95                 // dirs are alphabetically sorted
96                 year_name       = year_name_vector_param.at(0);
97                 string_to_number<int>(val_int, year_name, dec);
98                 date.year       = val_int;
99                 ret_val         = StoreCache::get_oldest_data(&date, device_id, PERIOD_YEARLY);
100         }
101         return ret_val;
102 }
103
104 DataRange *DataReader::get_data_range() {
105         DataRange       *ret_val;
106         vector<string>  y_list;
107         Data            *o_data;
108         Data            *n_data;
109
110         ret_val = NULL;
111         y_list  = FileUtil::get_subdirectories(device_dir);
112         o_data  = find_oldest_data(y_list);
113         if (o_data != NULL) {
114                 n_data  = find_latest_data(y_list);
115                 if (n_data != NULL) {
116                         ret_val = new DataRange(o_data);
117                         ret_val->add(n_data);
118                         delete(n_data);
119                 }
120                 delete(o_data);
121         }
122         return ret_val;
123 }
124
125 EnumSummaryPeriod get_period_type(Date *start_date,
126                         Date *end_date) {
127         int                     diff;
128         EnumSummaryPeriod       ret_val;
129
130         ret_val = PERIOD_YEARLY;
131         diff    = end_date->year - start_date->year;
132         if (diff != 0) {
133                 ret_val = PERIOD_YEARLY;
134         }
135         else {
136                 diff    = end_date->month - start_date->month;
137                 if (diff != 0) {
138                         ret_val = PERIOD_MONTHLY;
139                 }
140                 else {
141                         diff    = end_date->day - start_date->day;
142                         if (diff != 0) {
143                                 ret_val = PERIOD_DAILY;
144                         }
145                         else {
146                                 diff    = end_date->hour - start_date->hour;
147                                 if (diff != 0) {
148                                         ret_val = PERIOD_HOURLY;
149                                 }
150                                 else {
151                                         diff    = end_date->min - start_date->min;
152                                         if (diff != 0) {
153                                                 ret_val = PERIOD_MINUTELY;
154                                         }
155                                         else {
156                                                 ret_val = PERIOD_SECONDLY;
157                                         }
158                                 }
159                         }
160                 }
161         }
162         return ret_val;
163 }
164
165 DataRange *DataReader::get_summary(Date *date_param,
166                                 EnumSummaryCalculationType calc_type_param,
167                                 EnumSummaryPeriod period_type_param) {
168         DataRange       *ret_val;
169         StoreCache      *store;
170
171         ret_val = NULL;
172         //store = new StoreDay(device_id, date_param);
173         store   = new StoreCache(device_id, date_param);
174         if (store != NULL) {
175                 switch(calc_type_param) {
176                         case SUM:
177                                 ret_val = store->get_sum(period_type_param);
178                                 break;
179                         case DELTA:
180                                 ret_val = store->get_delta(period_type_param);
181                                 break;
182                         case MAX:
183                                 ret_val = store->get_max(period_type_param);
184                                 break;
185                         case MIN:
186                                 ret_val = store->get_min(period_type_param);
187                                 break;
188                         case MEAN:
189                         default:
190                                 ret_val = store->get_mean(period_type_param);
191                                 break;
192                 }
193                 if (ret_val != NULL) {
194                         ret_val->printout();
195                 }
196                 else {
197                         log_error("%s: Could not read data log for device %s. Data not found.\n",
198                                 date_param->to_string().c_str(),
199                                 device_id.c_str());
200                 }
201         }
202         else {
203                 log_error("%s: Could not read data log for device: %s. Memory allocation error..\n",
204                         date_param->to_string().c_str(),
205                         device_id.c_str());
206         }
207         delete(store);
208         return ret_val;
209 }
210
211 DataRange *DataReader::get_yearly_summary(Date *date,
212                                 EnumSummaryCalculationType calc_type_param) {
213         return get_summary(date, calc_type_param, PERIOD_YEARLY);
214 }
215
216 DataRange *DataReader::get_yearly_summary(Date *date) {
217         DataRange       *ret_val;
218
219         if (device_config == NULL) {
220                 device_config           = DeviceConfig::get_device_config(device_id);
221                 summary_calc_type       = device_config->get_summary_calculation_type();
222         }
223         ret_val = get_yearly_summary(date, summary_calc_type);
224         return ret_val;
225 }
226
227 DataRange *DataReader::get_yearly_summary(Date *start_date,
228                                         Date *end_date) {
229         DataRange       *ret_val;
230         DataRange       *data;
231         Date            *date;
232
233         ret_val = NULL;
234         date    = start_date->clone();
235         while(date->before_or_equal_year(end_date)) {
236                 if (StoreDay::exist_in_year(device_id, date, false)) {
237                         data    = get_yearly_summary(date);
238                         if (data != NULL) {
239                                 if (ret_val == NULL) {
240                                         ret_val = new DataRange(data);
241                                 }
242                                 else {
243                                         ret_val->add(data);
244                                 }
245                                 delete(data);
246                         }
247                 }
248                 date->next_year();
249         }
250         delete(date);
251         return ret_val;
252 }
253
254 DataRange *DataReader::get_monthly_summary(Date *date,
255                                 EnumSummaryCalculationType calc_type_param) {
256         return get_summary(date, calc_type_param, PERIOD_MONTHLY);
257 }
258
259 DataRange *DataReader::get_monthly_summary(Date *date) {
260         DataRange       *ret_val;
261
262         if (device_config == NULL) {
263                 device_config           = DeviceConfig::get_device_config(device_id);
264                 summary_calc_type       = device_config->get_summary_calculation_type();
265         }
266         ret_val = get_monthly_summary(date, summary_calc_type);
267         return ret_val;
268 }
269
270 DataRange *DataReader::get_monthly_summary(Date *start_date,
271                                         Date *end_date) {
272         DataRange       *ret_val;
273         DataRange       *data;
274         Date            *date;
275
276         ret_val = NULL;
277         date    = start_date->clone();
278         while(date->before_or_equal_month(end_date)) {
279                 if (StoreDay::exist_in_month(device_id, date, false)) {
280                         data    = get_monthly_summary(date);
281                         if (data != NULL) {
282                                 if (ret_val == NULL) {
283                                         ret_val = new DataRange(data);
284                                 }
285                                 else {
286                                         ret_val->add(data);
287                                 }
288                                 delete(data);
289                         }
290                         date->next_month();
291                 }
292         }
293         delete(date);
294         return ret_val;
295 }
296
297 /*
298  * Get Daily summary from the latest date
299  */
300 DataRange *DataReader::get_daily_summary() {
301         if (device_config == NULL) {
302                 device_config           = DeviceConfig::get_device_config(device_id);
303                 summary_calc_type       = device_config->get_summary_calculation_type();
304         }
305         return get_daily_summary(summary_calc_type);
306 }
307
308 /*
309  * Get Daily summary specified by the calc_type from the latest date.
310  */
311 DataRange *DataReader::get_daily_summary(EnumSummaryCalculationType calc_type_param) {
312         Data            *data;
313         Date            date;
314         DataRange       *ret_val;
315
316         ret_val = NULL;
317         data    = get_latest_data();
318         if (data != NULL) {
319                 date    = data->get_date();
320                 ret_val = get_daily_summary(&date, calc_type_param);
321                 delete(data);
322         }
323         return ret_val;
324 }
325
326 DataRange *DataReader::get_daily_summary(Date *date,
327                                 EnumSummaryCalculationType calc_type_param) {
328         return get_summary(date, calc_type_param, PERIOD_DAILY);
329 }
330
331 DataRange *DataReader::get_daily_summary(Date *date) {
332         DataRange       *ret_val;
333
334         if (device_config == NULL) {
335                 device_config           = DeviceConfig::get_device_config(device_id);
336                 summary_calc_type       = device_config->get_summary_calculation_type();
337         }
338         ret_val = get_daily_summary(date, summary_calc_type);
339         return ret_val;
340 }
341
342 DataRange *DataReader::get_daily_summary(Date *start_date,
343                                         Date *end_date) {
344         DataRange       *ret_val;
345         DataRange       *data;
346         Date            *date;
347
348         ret_val = NULL;
349         date    = start_date->clone();
350         while(date->before_or_equal_day(end_date)) {
351                 if (StoreDay::exist(device_id, date, false)) {
352                         data    = get_daily_summary(date);
353                         if (data != NULL) {
354                                 if (ret_val == NULL) {
355                                         ret_val = new DataRange(data);
356                                 }
357                                 else {
358                                         ret_val->add(data);
359                                 }
360                                 delete(data);
361                         }
362                 }
363                 date->next_day();
364         }
365         delete(date);
366         return ret_val;
367 }
368
369 DataRange *DataReader::get_hourly_summary(Date *date,
370                 EnumSummaryCalculationType calc_type_param) {
371         return get_summary(date, calc_type_param, PERIOD_HOURLY);
372 }
373
374 DataRange *DataReader::get_hourly_summary(Date *date) {
375         DataRange       *ret_val;
376
377         if (device_config == NULL) {
378                 device_config           = DeviceConfig::get_device_config(device_id);
379                 summary_calc_type       = device_config->get_summary_calculation_type();
380         }
381         ret_val = get_hourly_summary(date, summary_calc_type);
382         return ret_val;
383 }
384
385 DataRange *DataReader::get_hourly_summary(Date *start_date,
386                                         Date *end_date) {
387         DataRange       *ret_val;
388         DataRange       *dta_lst;
389         Data            *data;
390         Date            *date;
391         int             cnt;
392         int             ii;
393
394         ret_val = NULL;
395         date    = start_date->clone();
396         while(date->before_or_equal_hour(end_date)) {
397                 dta_lst = get_hourly_summary(date);
398                 cnt     = dta_lst->get_count();
399                 for(ii = 0; ii < cnt; ii++) {
400                         data    = dta_lst->get(ii);
401                         if (data != NULL) {
402                                 if (ret_val == NULL) {
403                                         ret_val = new DataRange(data);
404                                 }
405                                 else {
406                                         ret_val->add(data);
407                                 }
408                                 delete(data);
409                         }
410                 }
411                 date->next_day();
412         }
413         delete(date);
414         return ret_val;
415 }
416
417 DataRange *DataReader::get_data(Date *start_date,
418                                 Date *end_date) {
419         DataRange               *ret_val;
420         EnumSummaryPeriod       period;
421
422         ret_val = NULL;
423         period  = get_period_type(start_date, end_date);
424         switch(period) {
425                 case PERIOD_YEARLY:
426                         log_debug("get yearly summary: %s - %s\n", start_date->to_string().c_str(), end_date->to_string().c_str());
427                         ret_val = get_yearly_summary(start_date, end_date);
428                         break;
429                 case PERIOD_MONTHLY:
430                         log_debug("get monthly summary\n");
431                         ret_val = get_monthly_summary(start_date, end_date);
432                         break;
433                 case PERIOD_DAILY:
434                         log_debug("get daily summary\n");
435                         ret_val = get_daily_summary(start_date, end_date);
436                         break;
437                 case PERIOD_HOURLY:
438                         log_debug("get hourly summary\n");
439                         ret_val = get_hourly_summary(start_date, end_date);
440                         break;
441                 case PERIOD_MINUTELY:
442                         log_debug("get minute summary data\n");
443                         break;
444                 case PERIOD_SECONDLY:
445                 default:
446                         log_debug("get second summary data\n");
447                         break;
448         }
449         return ret_val;
450 }
451
452 string DataReader::get_device_id() {
453         return device_id;
454 }
455
456 /**
457  * Read device type from the device specific config file.
458  *
459  * @rerurn string representing device type.
460  * In the case of error, an empty string is returned.
461  */
462 bool DataReader::get_device_type(string& type_param) {
463         bool    ret_val;
464
465         ret_val = false;
466         if (device_config == NULL) {
467                 device_config   = DeviceConfig::get_device_config(device_id);
468         }
469         if (device_config != NULL) {
470                 ret_val = device_config->get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, type_param);
471         }
472         return ret_val;
473 }