]> pilppa.org Git - libplp.git/blob - src/StoreCache.cc
remove warning from possible uninitialized variable
[libplp.git] / src / StoreCache.cc
1 /*
2  * StoreCache.cc
3  *
4  *  Created on: Jan 6, 2011
5  *      Author: lamikr
6  */
7 #include <sstream>
8 #include <fstream>
9
10 #include "log.h"
11 #include "Store.hh"
12 #include "StoreCache.hh"
13 #include "StoreDay.hh"
14 #include "DeviceConfig.hh"
15 #include "FileUtil.hh"
16
17 using namespace std;
18 using namespace plp;
19
20 StoreCache::StoreCache(string device_id_param,
21         Date *date_time_param): Store(device_id_param, date_time_param) {
22 }
23
24 StoreCache::~StoreCache() {
25 }
26
27 string StoreCache::get_dir_name(string device_id_param,
28                                 Date *date_time_param,
29                                 EnumSummaryPeriod period_type_param,
30                                 EnumSummaryCalculationType calc_type_param) {
31         string  ret_val;
32         char    buffer[30];
33         string  bd_name;
34
35         bd_name = DeviceConfig::get_base_dir_name();
36         bd_name = FileUtil::concat_paths(bd_name, CACHE_DIR_NAME);
37         bd_name = FileUtil::concat_paths(bd_name, device_id_param);
38         bd_name = FileUtil::concat_paths(bd_name, SUMMARY_PERIOD_NAMES_ARRAY[period_type_param]);
39         bd_name = FileUtil::concat_paths(bd_name, CALCULATION_TYPE_NAMES_ARRAY[calc_type_param]);
40         if (period_type_param == PERIOD_YEARLY) {
41                 ret_val = bd_name;
42         }
43         else if (period_type_param == PERIOD_MONTHLY) {
44                 snprintf(buffer, 30, "%d", date_time_param->year);
45                 ret_val = bd_name + "/" + buffer;
46         }
47         else {
48                 snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
49                 ret_val = bd_name + "/" + buffer;
50         }
51         return ret_val;
52 }
53
54 string StoreCache::get_file_name(string device_id_param,
55                                 Date *date_time_param,
56                                 EnumSummaryPeriod period_type_param,
57                                 EnumSummaryCalculationType calc_type_param) {
58         string  ret_val;
59         string  fname;
60         char    buffer[30];
61
62         if (period_type_param == PERIOD_YEARLY) {
63                 snprintf(buffer, 30, "%d", date_time_param->year);
64         }
65         else if (period_type_param == PERIOD_MONTHLY) {
66                 snprintf(buffer, 30, "%d-%02d",
67                         date_time_param->year,
68                         date_time_param->month);
69         }
70         else {
71                 snprintf(buffer, 30, "%d-%02d-%02d",
72                         date_time_param->year,
73                         date_time_param->month,
74                         date_time_param->day);
75         }
76         fname   = buffer;
77         fname   = fname + DATAFILE_SUFFIX;
78         ret_val = get_dir_name(device_id_param, date_time_param, period_type_param, calc_type_param);
79         ret_val = FileUtil::concat_paths(ret_val, fname);
80         return ret_val;
81 }
82
83 plp::Date *StoreCache::get_scanning_limit_date(EnumSummaryPeriod period_type_param) {
84         Data    *cur_data;;
85         Date    *ret_val;
86
87         cur_data        = get_latest_data(date, device_id, period_type_param);
88         if (cur_data != NULL) {
89                 ret_val = cur_data->get_date().clone();
90                 ret_val->next_second();
91                 delete(cur_data);
92                 cur_data        = NULL;
93         }
94         else {
95                 ret_val = date->clone();
96                 if (period_type_param == PERIOD_YEARLY) {
97                         ret_val->next_year();
98                 }
99                 else {
100                         ret_val->next_month();
101                 }
102         }
103         return ret_val;
104 }
105
106 DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) {
107         int             row_count;
108         DataRange       *ret_val;
109         Data            *dta;
110         string          fname;
111
112         ret_val = NULL;
113         fname   = get_file_name(device_id,
114                                 date,
115                                 period_type_param,
116                                 MEAN);
117         if (store_data == NULL) {
118                 if (access(fname.c_str(), R_OK) == 0) {
119                         load(fname);
120                 }
121         }
122         if (store_data != NULL) {
123                 row_count       = store_data->get_count();
124                 if (row_count > 0) {
125                         ret_val = new DataRange();
126                         dta     = store_data->get(0);
127                         ret_val->add(dta);
128                         delete(dta);
129                 }
130         }
131         if (ret_val == NULL) {
132                 switch(period_type_param) {
133                         case PERIOD_YEARLY:
134                         case PERIOD_MONTHLY:
135                         {
136                                         Data            *cur_data;
137                                         Data            *res_data;
138                                         Date            *cur_date;
139                                         Date            *max_date;
140                                         int             ii;
141                                         int             cnt;
142                                         int             val_cnt;
143                                         DataRange       *dr;
144                                         Store           *store;
145
146                                         cur_date        = date->clone();
147                                         max_date        = get_scanning_limit_date(period_type_param);
148                                         cur_data        = NULL;
149                                         res_data        = NULL;
150                                         cnt             = 0;
151                                         val_cnt         = 0;
152                                         while(cur_date->before(max_date)) {
153                                                 if (period_type_param == PERIOD_YEARLY) {
154                                                         store   = new StoreCache(device_id, cur_date);
155                                                         dr      = store->get_mean(PERIOD_MONTHLY);
156                                                 }
157                                                 else {
158                                                         store   = new StoreDay(device_id, cur_date);
159                                                         dr      = store->get_mean(PERIOD_DAILY);
160                                                 }
161                                                 if (dr != NULL) {
162                                                         cur_data        = dr->get_first();
163                                                         if (cur_data != NULL) {
164                                                                 cnt++;
165                                                                 if (res_data == NULL) {
166                                                                         res_data        = cur_data;
167                                                                         val_cnt         = res_data->get_value_count();
168                                                                 }
169                                                                 else {
170                                                                         for (ii = 0; ii < val_cnt; ii++) {
171                                                                                 res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
172                                                                         }
173                                                                         delete(cur_data);
174                                                                 }
175                                                         }
176                                                         delete(dr);
177                                                 }
178                                                 delete(store);
179                                                 if (period_type_param == PERIOD_YEARLY) {
180                                                         cur_date->next_month();
181                                                 }
182                                                 else {
183                                                         cur_date->next_day();
184                                                 }
185                                         }
186                                         if ((res_data != NULL) &&
187                                             (cnt > 0)) {
188                                                 for (ii = 0; ii < val_cnt; ii++) {
189                                                         res_data->value_arr[ii] = res_data->value_arr[ii] / cnt;
190                                                 }
191                                                 ret_val = new DataRange(res_data);
192                                                 save(fname, ret_val, 4);
193                                                 delete(res_data);
194                                         }
195                                         delete(cur_date);
196                                         delete(max_date);
197                                 }
198                                 break;
199                         case PERIOD_DAILY:
200                         case PERIOD_HOURLY:
201                         case PERIOD_MINUTELY:
202                         case PERIOD_SECONDLY: {
203                                         StoreDay        *store;
204
205                                         store   = new StoreDay(device_id, date);
206                                         ret_val = store->get_mean(period_type_param);
207                                         if ((period_type_param != PERIOD_MINUTELY) ||
208                                             (period_type_param != PERIOD_SECONDLY)) {
209                                                 // no need cache second or minute data
210                                                 save(fname, ret_val, 4);
211                                         }
212                                         delete(store);
213                                 }
214                                 break;
215                 }
216         }
217         return ret_val;
218 }
219
220 DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) {
221         int             row_count;
222         DataRange       *ret_val;
223         Data            *dta;
224         string          fname;
225         Store           *store;
226
227         ret_val = NULL;
228         fname   = get_file_name(device_id,
229                                 date,
230                                 period_type_param,
231                                 SUM);
232         if (store_data == NULL) {
233                 if (access(fname.c_str(), R_OK) == 0) {
234                         load(fname);
235                 }
236         }
237         if (store_data != NULL) {
238                 row_count       = store_data->get_count();
239                 if (row_count > 0) {
240                         ret_val = new DataRange();
241                         dta     = store_data->get(0);
242                         ret_val->add(dta);
243                         delete(dta);
244                 }
245         }
246         if (ret_val == NULL) {
247                 switch(period_type_param) {
248                         case PERIOD_YEARLY:
249                         case PERIOD_MONTHLY: {
250                                         Data            *cur_data;
251                                         Data            *res_data;
252                                         Date            *cur_date;
253                                         Date            *max_date;
254                                         int             ii;
255                                         int             cnt;
256                                         int             val_cnt;
257                                         DataRange       *dr;
258
259                                         cur_date        = date->clone();
260                                         max_date        = get_scanning_limit_date(period_type_param);
261                                         cur_data        = NULL;
262                                         res_data        = NULL;
263                                         cnt             = 0;
264                                         while(cur_date->before(max_date)) {
265                                                 if (period_type_param == PERIOD_YEARLY) {
266                                                         store   = new StoreCache(device_id, cur_date);
267                                                         dr      = store->get_sum(PERIOD_MONTHLY);
268                                                 }
269                                                 else {
270                                                         store   = new StoreDay(device_id, cur_date);
271                                                         dr      = store->get_sum(PERIOD_DAILY);
272                                                 }
273                                                 if (dr != NULL) {
274                                                         cur_data        = dr->get_first();
275                                                         if (cur_data != NULL) {
276                                                                 cnt++;
277                                                                 if (res_data == NULL) {
278                                                                         res_data        = cur_data;
279                                                                 }
280                                                                 else {
281                                                                         val_cnt = res_data->get_value_count();
282                                                                         for (ii = 0; ii < val_cnt; ii++) {
283                                                                                 res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
284                                                                         }
285                                                                         delete(cur_data);
286                                                                 }
287                                                         }
288                                                         delete(dr);
289                                                 }
290                                                 delete(store);
291                                                 if (period_type_param == PERIOD_YEARLY) {
292                                                         cur_date->next_month();
293                                                 }
294                                                 else {
295                                                         cur_date->next_day();
296                                                 }
297                                         }
298                                         if ((res_data != NULL) &&
299                                             (cnt > 0)) {
300                                                 ret_val = new DataRange(res_data);
301                                                 save(fname, ret_val, 4);
302                                                 delete(res_data);
303                                         }
304                                         delete(cur_date);
305                                         delete(max_date);
306                                 }
307                                 break;
308                         case PERIOD_DAILY:
309                         case PERIOD_HOURLY:
310                         case PERIOD_MINUTELY:
311                         case PERIOD_SECONDLY:
312                                 store   = new StoreDay(device_id, date);
313                                 ret_val = store->get_sum(period_type_param);
314                                 if ((period_type_param != PERIOD_MINUTELY) ||
315                                     (period_type_param != PERIOD_SECONDLY)) {
316                                         // no need cache second or minute data
317                                         save(fname, ret_val, 4);
318                                 }
319                                 delete(store);
320                                 break;
321                 }
322         }
323         return ret_val;
324 }
325
326 DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) {
327         int             row_count;
328         DataRange       *ret_val;
329         Data            *dta;
330         string          fname;
331         StoreDay        *store;
332
333         ret_val = NULL;
334         fname   = get_file_name(device_id,
335                                 date,
336                                 period_type_param,
337                                 DELTA);
338         if (store_data == NULL) {
339                 if (access(fname.c_str(), R_OK) == 0) {
340                         // read from cache file
341                         load(fname);
342                 }
343         }
344         if (store_data != NULL) {
345                 row_count       = store_data->get_count();
346                 if (row_count > 0) {
347                         ret_val = new DataRange();
348                         dta     = store_data->get(0);
349                         ret_val->add(dta);
350                         delete(dta);
351                 }
352         }
353         if (ret_val == NULL) {
354                 switch(period_type_param) {
355                         case PERIOD_YEARLY: {
356                                         Data    *first_data;
357                                         Data    *last_data;
358                                         int     ii;
359                                         int     cnt;
360
361                                         first_data      = get_oldest_data(date, device_id, PERIOD_YEARLY);
362                                         if (first_data != NULL) {
363                                                 last_data       = get_latest_data(date, device_id, PERIOD_YEARLY);
364                                                 if (last_data != NULL) {
365                                                         ret_val         = new DataRange();
366                                                         cnt             = last_data->get_value_count();
367                                                         for (ii = 0; ii < cnt; ii++) {
368                                                                 last_data->value_arr[ii]        = last_data->value_arr[ii] - first_data->value_arr[ii];
369                                                         }
370                                                         ret_val->add(last_data);
371                                                         delete(last_data);
372                                                 }
373                                                 delete(first_data);
374                                                 save(fname, ret_val, 4);
375                                         }
376                                         else {
377                                                 log_error("Could not read first or last data item from device %s for year: %d", device_id.c_str(), date->year);
378                                         }
379                                 }
380                                 break;
381                         case PERIOD_MONTHLY: {
382                                         Data    *first_data;
383                                         Data    *last_data;
384                                         Data    *cur_data;
385                                         Date    *cur_date;
386                                         Date    *limit_date;
387                                         int     ii;
388                                         int     cnt;
389
390                                         cur_date        = date->clone();
391                                         limit_date      = date->clone();
392                                         limit_date->next_month();
393                                         first_data      = NULL;
394                                         last_data       = NULL;
395                                         while(cur_date->before(limit_date)) {
396                                                 store   = new StoreDay(device_id, cur_date);
397                                                 if (first_data == NULL) {
398                                                         cur_data        = store->get_oldest_data();
399                                                         if (cur_data != NULL) {
400                                                                 first_data      = cur_data->clone();
401                                                                 last_data       = cur_data->clone();
402                                                                 delete(cur_data);
403                                                         }
404                                                 }
405                                                 cur_data        = store->get_latest_data();
406                                                 if (cur_data != NULL) {
407                                                         if (last_data != NULL) {
408                                                                 delete(last_data);
409                                                         }
410                                                         last_data       = cur_data;
411                                                 }
412                                                 delete(store);
413                                                 cur_date->next_day();
414                                         }
415                                         delete(cur_date);
416                                         delete(limit_date);
417                                         if (first_data != NULL) {
418                                                 if (last_data == NULL) {
419                                                         last_data       = first_data->clone();
420                                                 }
421                                                 cnt     = last_data->get_value_count();
422                                                 for (ii = 0; ii < cnt; ii++) {
423                                                         last_data->value_arr[ii]        = last_data->value_arr[ii] - first_data->value_arr[ii];
424                                                 }
425                                                 cur_date        = first_data->get_date().clone();
426                                                 last_data->set_date(cur_date);
427                                                 delete(cur_date);
428                                                 ret_val = new DataRange(last_data);
429                                                 delete(first_data);
430                                                 delete(last_data);
431                                                 save(fname, ret_val, 4);
432                                         }
433                                 }
434                                 break;
435                         case PERIOD_DAILY:
436                         case PERIOD_HOURLY:
437                         case PERIOD_MINUTELY:
438                         case PERIOD_SECONDLY:
439                                 store   = new StoreDay(device_id, date);
440                                 ret_val = store->get_delta(period_type_param);
441                                 if ((period_type_param != PERIOD_MINUTELY) ||
442                                     (period_type_param != PERIOD_SECONDLY)) {
443                                         // no need cache second or minute data
444                                         save(fname, ret_val, 4);
445                                 }
446                                 delete(store);
447                                 break;
448                 }
449         }
450         return ret_val;
451 }
452
453 DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) {
454         int             row_count;
455         DataRange       *ret_val;
456         Data            *dta;
457         string          fname;
458         Store           *store;
459
460         ret_val = NULL;
461         fname   = get_file_name(device_id,
462                                 date,
463                                 period_type_param,
464                                 MAX);
465         if (store_data == NULL) {
466                 if (access(fname.c_str(), R_OK) == 0) {
467                         load(fname);
468                 }
469         }
470         if (store_data != NULL) {
471                 row_count       = store_data->get_count();
472                 if (row_count > 0) {
473                         ret_val = new DataRange();
474                         dta     = store_data->get(0);
475                         ret_val->add(dta);
476                         delete(dta);
477                 }
478         }
479         if (ret_val == NULL) {
480                 switch(period_type_param) {
481                         case PERIOD_YEARLY:
482                         case PERIOD_MONTHLY: {
483                                         Data            *cur_data;
484                                         Data            *res_data;
485                                         Date            *cur_date;
486                                         Date            *max_date;
487                                         int             ii;
488                                         int             cnt;
489                                         int             val_cnt;
490                                         DataRange       *dr;
491
492                                         cur_date        = date->clone();
493                                         max_date        = get_scanning_limit_date(period_type_param);
494                                         cur_data        = NULL;
495                                         res_data        = NULL;
496                                         cnt             = 0;
497                                         while(cur_date->before(max_date)) {
498                                                 if (period_type_param == PERIOD_YEARLY) {
499                                                         store   = new StoreCache(device_id, cur_date);
500                                                         dr      = store->get_max(PERIOD_MONTHLY);
501                                                 }
502                                                 else {
503                                                         store   = new StoreDay(device_id, cur_date);
504                                                         dr      = store->get_max(PERIOD_DAILY);
505                                                 }
506                                                 if (dr != NULL) {
507                                                         cur_data        = dr->get_first();
508                                                         if (cur_data != NULL) {
509                                                                 cnt++;
510                                                                 if (res_data == NULL) {
511                                                                         res_data        = cur_data;
512                                                                 }
513                                                                 else {
514                                                                         val_cnt = res_data->get_value_count();
515                                                                         int changed = 0;
516                                                                         for (ii = 0; ii < val_cnt; ii++) {
517                                                                                 if (cur_data->value_arr[ii] > res_data->value_arr[ii]) {
518                                                                                         res_data->value_arr[ii] = cur_data->value_arr[ii];
519                                                                                         changed = 1;
520                                                                                 }
521                                                                         }
522                                                                         if (changed == 1) {
523                                                                                 Date new_date;
524
525                                                                                 new_date        = cur_data->get_date();
526                                                                                 res_data->set_date(&new_date);
527                                                                         }
528                                                                         delete(cur_data);
529                                                                 }
530                                                         }
531                                                         delete(dr);
532                                                 }
533                                                 delete(store);
534                                                 if (period_type_param == PERIOD_YEARLY) {
535                                                         cur_date->next_month();
536                                                 }
537                                                 else {
538                                                         cur_date->next_day();
539                                                 }
540                                         }
541                                         if ((res_data != NULL) &&
542                                             (cnt > 0)) {
543                                                 ret_val = new DataRange(res_data);
544                                                 save(fname, ret_val, 4);
545                                                 delete(res_data);
546                                         }
547                                         delete(cur_date);
548                                         delete(max_date);
549                                 }
550                                 break;
551                         case PERIOD_DAILY:
552                         case PERIOD_HOURLY:
553                         case PERIOD_MINUTELY:
554                         case PERIOD_SECONDLY:
555                                 store   = new StoreDay(device_id, date);
556                                 ret_val = store->get_max(period_type_param);
557                                 if ((period_type_param != PERIOD_MINUTELY) ||
558                                     (period_type_param != PERIOD_SECONDLY)) {
559                                         // no need cache second or minute data
560                                         save(fname, ret_val, 4);
561                                 }
562                                 delete(store);
563                                 break;
564                 }
565         }
566         return ret_val;
567 }
568
569 DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) {
570         int             row_count;
571         DataRange       *ret_val;
572         Data            *dta;
573         string          fname;
574         Store           *store;
575
576         ret_val = NULL;
577         fname   = get_file_name(device_id,
578                                 date,
579                                 period_type_param,
580                                 MIN);
581         if (store_data == NULL) {
582                 if (access(fname.c_str(), R_OK) == 0) {
583                         load(fname);
584                 }
585         }
586         if (store_data != NULL) {
587                 row_count       = store_data->get_count();
588                 if (row_count > 0) {
589                         ret_val = new DataRange();
590                         dta     = store_data->get(0);
591                         ret_val->add(dta);
592                         delete(dta);
593                 }
594         }
595         if (ret_val == NULL) {
596                 switch(period_type_param) {
597                         case PERIOD_YEARLY:
598                         case PERIOD_MONTHLY: {
599                                         Data            *cur_data;
600                                         Data            *res_data;
601                                         Date            *cur_date;
602                                         Date            *max_date;
603                                         int             ii;
604                                         int             cnt;
605                                         int             val_cnt;
606                                         DataRange       *dr;
607
608                                         cur_date        = date->clone();
609                                         max_date        = get_scanning_limit_date(period_type_param);
610                                         cur_data        = NULL;
611                                         res_data        = NULL;
612                                         cnt             = 0;
613                                         while(cur_date->before(max_date)) {
614                                                 if (period_type_param == PERIOD_YEARLY) {
615                                                         store   = new StoreCache(device_id, cur_date);
616                                                         dr      = store->get_min(PERIOD_MONTHLY);
617                                                 }
618                                                 else {
619                                                         store   = new StoreDay(device_id, cur_date);
620                                                         dr      = store->get_min(PERIOD_DAILY);
621                                                 }
622                                                 if (dr != NULL) {
623                                                         cur_data        = dr->get_first();
624                                                         if (cur_data != NULL) {
625                                                                 cnt++;
626                                                                 if (res_data == NULL) {
627                                                                         res_data        = cur_data;
628                                                                 }
629                                                                 else {
630                                                                         val_cnt = res_data->get_value_count();
631                                                                         int changed = 0;
632                                                                         for (ii = 0; ii < val_cnt; ii++) {
633                                                                                 if (cur_data->value_arr[ii] < res_data->value_arr[ii]) {
634                                                                                         res_data->value_arr[ii] = cur_data->value_arr[ii];
635                                                                                         changed = 1;
636                                                                                 }
637                                                                         }
638                                                                         if (changed == 1) {
639                                                                                 Date new_date;
640
641                                                                                 new_date        = cur_data->get_date();
642                                                                                 res_data->set_date(&new_date);
643                                                                         }
644                                                                         delete(cur_data);
645                                                                 }
646                                                         }
647                                                         delete(dr);
648                                                 }
649                                                 delete(store);
650                                                 if (period_type_param == PERIOD_YEARLY) {
651                                                         cur_date->next_month();
652                                                 }
653                                                 else {
654                                                         cur_date->next_day();
655                                                 }
656                                         }
657                                         if ((res_data != NULL) &&
658                                             (cnt > 0)) {
659                                                 ret_val = new DataRange(res_data);
660                                                 save(fname, ret_val, 4);
661                                                 delete(res_data);
662                                         }
663                                         delete(cur_date);
664                                         delete(max_date);
665                                 }
666                                 break;
667                         case PERIOD_DAILY:
668                         case PERIOD_HOURLY:
669                         case PERIOD_MINUTELY:
670                         case PERIOD_SECONDLY:
671                                 store   = new StoreDay(device_id, date);
672                                 ret_val = store->get_min(period_type_param);
673                                 if ((period_type_param != PERIOD_MINUTELY) ||
674                                     (period_type_param != PERIOD_SECONDLY)) {
675                                         // no need cache second or minute data
676                                         save(fname, ret_val, 4);
677                                 }
678                                 delete(store);
679                                 break;
680                 }
681         }
682         return ret_val;
683 }
684
685 void StoreCache::save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param) {
686         string          line;
687         Data            *data;
688         ofstream        *ostream;
689         int             ii;
690         int             cnt;
691
692         cnt     = datarange_param->get_count();
693         ostream =  NULL;
694         //log_info("[%s] cacheing %d data values.\n", device_id.c_str(), cnt);
695         ostream = FileUtil::open_for_writing(fname_param.c_str());
696         if ((ostream != NULL) &&
697             (ostream->is_open() == true)) {
698                 // TODO: add mutex to protect string_list while it's read and emptied
699                 for(ii = 0; ii < cnt; ii++) {
700                         data    = datarange_param->get(ii);
701                         if (data != NULL) {
702                                 line    = data->to_string(decimal_count_param);
703                                 if (line.length() > 0) {
704                                         *ostream << line << endl;
705                                 }
706                                 delete(data);
707                         }
708                 }
709         }
710         else {
711                 log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), fname_param.c_str());
712         }
713         if (ostream != NULL) {
714                 ostream->close();
715                 delete(ostream);
716         }
717 }
718
719 Data *StoreCache::get_oldest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) {
720         int             size;
721         unsigned int    ii;
722         string          year_dr;
723         string          mon_dr;
724         vector<string>  mon_vcr;
725         vector<string>  dta_vcr;
726         string          f_name;
727         StoreDay        *store;
728         Data            *ret_val;
729         string          device_dir;
730         char            buffer[30];
731         string          year_name;
732
733         ret_val = NULL;
734         if (period_type_param == PERIOD_YEARLY) {
735                 snprintf(buffer, 30, "%d", date_param->year);
736                 year_name.append(buffer);
737                 device_dir      = DeviceConfig::get_base_dir_name();
738                 device_dir      = FileUtil::concat_paths(device_dir, device_id_param);
739                 year_dr = FileUtil::concat_paths(device_dir, year_name);
740                 mon_vcr = FileUtil::get_subdirectories(year_dr);
741                 for (ii = 0; ii < mon_vcr.size(); ii++) {
742                         mon_dr  = mon_vcr.at(ii);
743                         mon_dr  = FileUtil::concat_paths(year_dr, mon_dr);
744                         // scan data files from month dir
745                         dta_vcr = FileUtil::get_data_files(mon_dr);
746                         size    = dta_vcr.size();
747                         if (size > 0) {
748                                 f_name  = dta_vcr.at(0);
749                                 f_name  = FileUtil::concat_paths(mon_dr, f_name);
750                                 store   = new StoreDay(f_name);
751                                 ret_val = store->get_oldest_data();
752                                 delete(store);
753                                 break;
754                         }
755                 }
756         }
757         else if (period_type_param == PERIOD_MONTHLY) {
758                 ret_val         = NULL;
759                 snprintf(buffer, 30, "%d", date_param->year);
760                 year_name.append(buffer);
761                 device_dir      = DeviceConfig::get_base_dir_name();
762                 device_dir      = FileUtil::concat_paths(device_dir, device_id_param);
763                 year_dr         = FileUtil::concat_paths(device_dir, year_name);
764                 snprintf(buffer, 30, "%02d", date_param->month);
765                 mon_dr.append(buffer);
766                 mon_dr          = FileUtil::concat_paths(year_dr, mon_dr);
767                 // scan data files from month dir
768                 dta_vcr         = FileUtil::get_data_files(mon_dr);
769                 size            = dta_vcr.size();
770                 if (size > 0) {
771                         f_name  = dta_vcr.at(0);
772                         f_name  = FileUtil::concat_paths(mon_dr, f_name);
773                         store   = new StoreDay(f_name);
774                         ret_val = store->get_oldest_data();
775                         delete(store);
776                 }
777
778         }
779         else {
780                 store   = new StoreDay(device_id_param, date_param);
781                 ret_val = store->get_oldest_data();
782                 delete(store);
783         }
784         return ret_val;
785 }
786
787 Data *StoreCache::get_latest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) {
788         int             ii;
789         string          mon_dr;
790         vector<string>  mon_vcr;
791         vector<string>  dta_vcr;
792         string          f_name;
793         StoreDay        *store;
794         Data            *ret_val;
795         string          year_dr;
796         int             size;
797         string          device_dir;
798         char            buffer[30];
799         string          year_name;
800
801         ret_val = NULL;
802         if (period_type_param == PERIOD_YEARLY) {
803                 snprintf(buffer, 30, "%d", date_param->year);
804                 year_name.append(buffer);
805                 device_dir      = DeviceConfig::get_base_dir_name();
806                 device_dir      = FileUtil::concat_paths(device_dir, device_id_param);
807                 year_dr = FileUtil::concat_paths(device_dir, year_name);
808                 mon_vcr = FileUtil::get_subdirectories(year_dr);
809                 for (ii = mon_vcr.size() - 1; ii >= 0; ii--) {
810                         mon_dr  = mon_vcr.at(ii);
811                         mon_dr  = FileUtil::concat_paths(year_dr, mon_dr);
812                         // scan data files from month dir
813                         dta_vcr = FileUtil::get_data_files(mon_dr);
814                         size    = dta_vcr.size();
815                         if (size > 0) {
816                                 f_name  = dta_vcr.at(size - 1);
817                                 f_name  = FileUtil::concat_paths(mon_dr, f_name);
818                                 store   = new StoreDay(f_name);
819                                 ret_val = store->get_latest_data();
820                                 delete(store);
821                                 break;
822                         }
823                 }
824         }
825         else if (period_type_param == PERIOD_MONTHLY) {
826                 ret_val         = NULL;
827                 snprintf(buffer, 30, "%d", date_param->year);
828                 year_name.append(buffer);
829                 device_dir      = DeviceConfig::get_base_dir_name();
830                 device_dir      = FileUtil::concat_paths(device_dir, device_id_param);
831                 year_dr         = FileUtil::concat_paths(device_dir, year_name);
832                 snprintf(buffer, 30, "%02d", date_param->month);
833                 mon_dr.append(buffer);
834                 mon_dr          = FileUtil::concat_paths(year_dr, mon_dr);
835                 // scan data files from month dir
836                 dta_vcr         = FileUtil::get_data_files(mon_dr);
837                 size            = dta_vcr.size();
838                 if (size > 0) {
839                         f_name  = dta_vcr.at(size - 1);
840                         f_name  = FileUtil::concat_paths(mon_dr, f_name);
841                         store   = new StoreDay(f_name);
842                         ret_val = store->get_latest_data();
843                         delete(store);
844                 }
845
846         }
847         else {
848                 store   = new StoreDay(device_id_param, date_param);
849                 ret_val = store->get_latest_data();
850                 delete(store);
851         }
852         return ret_val;
853 }