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