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