]> pilppa.org Git - lib1wire.git/blob - src/StoreCache.cc
No need to cache data calculated per minute or per secondly as the cache
[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 "DeviceData.hh"
14 #include "W1Util.hh"
15
16 using namespace std;
17 using namespace plp;
18 using namespace w1;
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 = W1Util::concat_paths(bd_name, CACHE_DIR_NAME);
37         bd_name = W1Util::concat_paths(bd_name, device_id_param);
38         bd_name = W1Util::concat_paths(bd_name, SUMMARY_PERIOD_NAMES_ARRAY[period_type_param]);
39         bd_name = W1Util::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 = W1Util::concat_paths(ret_val, fname);
80         return ret_val;
81 }
82
83 DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) {
84         int             row_count;
85         DataRange       *ret_val;
86         Data            *dta;
87         string          fname;
88
89         ret_val = NULL;
90         fname   = get_file_name(device_id,
91                                 date,
92                                 period_type_param,
93                                 MEAN);
94         if (store_data == NULL) {
95                 if (access(fname.c_str(), R_OK) == 0) {
96                         load(fname);
97                 }
98         }
99         if (store_data != NULL) {
100                 row_count       = store_data->get_count();
101                 if (row_count > 0) {
102                         ret_val = new DataRange();
103                         dta     = store_data->get(0);
104                         ret_val->add(dta);
105                         delete(dta);
106                 }
107         }
108         if (ret_val == NULL) {
109                 switch(period_type_param) {
110                         case PERIOD_YEARLY:
111                         case PERIOD_MONTHLY:
112                         {
113                                         Data            *cur_data;
114                                         Data            *res_data;
115                                         Date            *cur_date;
116                                         Date            *max_date;
117                                         int             ii;
118                                         int             cnt;
119                                         int             val_cnt;
120                                         DataRange       *dr;
121                                         Store           *store;
122
123                                         cur_date        = date->clone();
124                                         max_date        = date->clone();
125                                         if (period_type_param == PERIOD_YEARLY) {
126                                                 max_date->next_year();
127                                         }
128                                         else {
129                                                 max_date->next_month();
130                                         }
131                                         cur_data        = NULL;
132                                         res_data        = NULL;
133                                         cnt             = 0;
134                                         while(cur_date->before(max_date)) {
135                                                 if (period_type_param == PERIOD_YEARLY) {
136                                                         store   = new StoreCache(device_id, cur_date);
137                                                         dr      = store->get_mean(PERIOD_MONTHLY);
138                                                 }
139                                                 else {
140                                                         store   = new StoreDay(device_id, cur_date);
141                                                         dr      = store->get_mean(PERIOD_DAILY);
142                                                 }
143                                                 if (dr != NULL) {
144                                                         cur_data        = dr->get_first();
145                                                         if (cur_data != NULL) {
146                                                                 cnt++;
147                                                                 if (res_data == NULL) {
148                                                                         res_data        = cur_data;
149                                                                         val_cnt         = res_data->get_value_count();
150                                                                 }
151                                                                 else {
152                                                                         for (ii = 0; ii < val_cnt; ii++) {
153                                                                                 res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
154                                                                         }
155                                                                         delete(cur_data);
156                                                                 }
157                                                         }
158                                                         delete(dr);
159                                                 }
160                                                 delete(store);
161                                                 if (period_type_param == PERIOD_YEARLY) {
162                                                         cur_date->next_month();
163                                                 }
164                                                 else {
165                                                         cur_date->next_day();
166                                                 }
167                                         }
168                                         if ((res_data != NULL) &&
169                                             (cnt > 0)) {
170                                                 for (ii = 0; ii < val_cnt; ii++) {
171                                                         res_data->value_arr[ii] = res_data->value_arr[ii] / cnt;
172                                                 }
173                                                 ret_val = new DataRange(res_data);
174                                                 save(fname, ret_val, 4);
175                                                 delete(res_data);
176                                         }
177                                         delete(cur_date);
178                                         delete(max_date);
179                                 }
180                                 break;
181                         case PERIOD_DAILY:
182                         case PERIOD_HOURLY:
183                         case PERIOD_MINUTELY:
184                         case PERIOD_SECONDLY: {
185                                         StoreDay        *store;
186
187                                         store   = new StoreDay(device_id, date);
188                                         ret_val = store->get_mean(period_type_param);
189                                         if ((period_type_param != PERIOD_MINUTELY) ||
190                                             (period_type_param != PERIOD_SECONDLY)) {
191                                                 // no need cache second or minute data
192                                                 save(fname, ret_val, 4);
193                                         }
194                                         delete(store);
195                                 }
196                                 break;
197                 }
198         }
199         return ret_val;
200 }
201
202 DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) {
203         int             row_count;
204         DataRange       *ret_val;
205         Data            *dta;
206         string          fname;
207         Store           *store;
208
209         ret_val = NULL;
210         fname   = get_file_name(device_id,
211                                 date,
212                                 period_type_param,
213                                 SUM);
214         if (store_data == NULL) {
215                 if (access(fname.c_str(), R_OK) == 0) {
216                         load(fname);
217                 }
218         }
219         if (store_data != NULL) {
220                 row_count       = store_data->get_count();
221                 if (row_count > 0) {
222                         ret_val = new DataRange();
223                         dta     = store_data->get(0);
224                         ret_val->add(dta);
225                         delete(dta);
226                 }
227         }
228         if (ret_val == NULL) {
229                 switch(period_type_param) {
230                         case PERIOD_YEARLY:
231                         case PERIOD_MONTHLY: {
232                                         Data            *cur_data;
233                                         Data            *res_data;
234                                         Date            *cur_date;
235                                         Date            *max_date;
236                                         int             ii;
237                                         int             cnt;
238                                         int             val_cnt;
239                                         DataRange       *dr;
240
241                                         cur_date        = date->clone();
242                                         max_date        = date->clone();
243                                         if (period_type_param == PERIOD_YEARLY) {
244                                                 max_date->next_year();
245                                         }
246                                         else {
247                                                 max_date->next_month();
248                                         }
249                                         cur_data        = NULL;
250                                         res_data        = NULL;
251                                         cnt             = 0;
252                                         while(cur_date->before(max_date)) {
253                                                 if (period_type_param == PERIOD_YEARLY) {
254                                                         store   = new StoreCache(device_id, cur_date);
255                                                         dr      = store->get_sum(PERIOD_MONTHLY);
256                                                 }
257                                                 else {
258                                                         store   = new StoreDay(device_id, cur_date);
259                                                         dr      = store->get_sum(PERIOD_DAILY);
260                                                 }
261                                                 if (dr != NULL) {
262                                                         cur_data        = dr->get_first();
263                                                         if (cur_data != NULL) {
264                                                                 cnt++;
265                                                                 if (res_data == NULL) {
266                                                                         res_data        = cur_data;
267                                                                 }
268                                                                 else {
269                                                                         val_cnt = res_data->get_value_count();
270                                                                         for (ii = 0; ii < val_cnt; ii++) {
271                                                                                 res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
272                                                                         }
273                                                                         delete(cur_data);
274                                                                 }
275                                                         }
276                                                         delete(dr);
277                                                 }
278                                                 delete(store);
279                                                 if (period_type_param == PERIOD_YEARLY) {
280                                                         cur_date->next_month();
281                                                 }
282                                                 else {
283                                                         cur_date->next_day();
284                                                 }
285                                         }
286                                         if ((res_data != NULL) &&
287                                             (cnt > 0)) {
288                                                 ret_val = new DataRange(res_data);
289                                                 save(fname, ret_val, 4);
290                                                 delete(res_data);
291                                         }
292                                         delete(cur_date);
293                                         delete(max_date);
294                                 }
295                                 break;
296                         case PERIOD_DAILY:
297                         case PERIOD_HOURLY:
298                         case PERIOD_MINUTELY:
299                         case PERIOD_SECONDLY:
300                                 store   = new StoreDay(device_id, date);
301                                 ret_val = store->get_sum(period_type_param);
302                                 if ((period_type_param != PERIOD_MINUTELY) ||
303                                     (period_type_param != PERIOD_SECONDLY)) {
304                                         // no need cache second or minute data
305                                         save(fname, ret_val, 4);
306                                 }
307                                 delete(store);
308                                 break;
309                 }
310         }
311         return ret_val;
312 }
313
314 DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) {
315         int             row_count;
316         DataRange       *ret_val;
317         Data            *dta;
318         string          fname;
319         StoreDay        *store;
320
321         ret_val = NULL;
322         fname   = get_file_name(device_id,
323                                 date,
324                                 period_type_param,
325                                 DELTA);
326         if (store_data == NULL) {
327                 if (access(fname.c_str(), R_OK) == 0) {
328                         // read from cache file
329                         load(fname);
330                 }
331         }
332         if (store_data != NULL) {
333                 row_count       = store_data->get_count();
334                 if (row_count > 0) {
335                         ret_val = new DataRange();
336                         dta     = store_data->get(0);
337                         ret_val->add(dta);
338                         delete(dta);
339                 }
340         }
341         if (ret_val == NULL) {
342                 switch(period_type_param) {
343                         case PERIOD_YEARLY: {
344                                         Data    *first_data;
345                                         Data    *last_data;
346                                         int     ii;
347                                         int     cnt;
348
349                                         first_data      = get_year_oldest_data();
350                                         if (first_data != NULL) {
351                                                 last_data       = get_year_newest_data();
352                                                 if (last_data != NULL) {
353                                                         ret_val         = new DataRange();
354                                                         cnt             = last_data->get_value_count();
355                                                         for (ii = 0; ii < cnt; ii++) {
356                                                                 last_data->value_arr[ii]        = last_data->value_arr[ii] - first_data->value_arr[ii];
357                                                         }
358                                                         ret_val->add(last_data);
359                                                         delete(last_data);
360                                                 }
361                                                 delete(first_data);
362                                                 save(fname, ret_val, 4);
363                                         }
364                                         else {
365                                                 log_error("Could not read first or last data item from device %s for year: %d", device_id.c_str(), date->year);
366                                         }
367                                 }
368                                 break;
369                         case PERIOD_MONTHLY: {
370                                         Data    *first_data;
371                                         Data    *last_data;
372                                         Data    *cur_data;
373                                         Date    *cur_date;
374                                         Date    *limit_date;
375                                         int     ii;
376                                         int     cnt;
377
378                                         cur_date        = date->clone();
379                                         limit_date      = date->clone();
380                                         limit_date->next_month();
381                                         first_data      = NULL;
382                                         last_data       = NULL;
383                                         while(cur_date->before(limit_date)) {
384                                                 store   = new StoreDay(device_id, cur_date);
385                                                 if (first_data == NULL) {
386                                                         cur_data        = store->get_oldest_data();
387                                                         if (cur_data != NULL) {
388                                                                 first_data      = cur_data->clone();
389                                                                 last_data       = cur_data->clone();
390                                                                 delete(cur_data);
391                                                         }
392                                                 }
393                                                 cur_data        = store->get_newest_data();
394                                                 if (cur_data != NULL) {
395                                                         if (last_data != NULL) {
396                                                                 delete(last_data);
397                                                         }
398                                                         last_data       = cur_data;
399                                                 }
400                                                 delete(store);
401                                                 cur_date->next_day();
402                                         }
403                                         delete(cur_date);
404                                         delete(limit_date);
405                                         if (first_data != NULL) {
406                                                 if (last_data == NULL) {
407                                                         last_data       = first_data->clone();
408                                                 }
409                                                 cnt     = last_data->get_value_count();
410                                                 for (ii = 0; ii < cnt; ii++) {
411                                                         last_data->value_arr[ii]        = last_data->value_arr[ii] - first_data->value_arr[ii];
412                                                 }
413                                                 cur_date        = first_data->get_date().clone();
414                                                 last_data->set_date(cur_date);
415                                                 delete(cur_date);
416                                                 ret_val = new DataRange(last_data);
417                                                 delete(first_data);
418                                                 delete(last_data);
419                                                 save(fname, ret_val, 4);
420                                         }
421                                 }
422                                 break;
423                         case PERIOD_DAILY:
424                         case PERIOD_HOURLY:
425                         case PERIOD_MINUTELY:
426                         case PERIOD_SECONDLY:
427                                 store   = new StoreDay(device_id, date);
428                                 ret_val = store->get_delta(period_type_param);
429                                 if ((period_type_param != PERIOD_MINUTELY) ||
430                                     (period_type_param != PERIOD_SECONDLY)) {
431                                         // no need cache second or minute data
432                                         save(fname, ret_val, 4);
433                                 }
434                                 delete(store);
435                                 break;
436                 }
437         }
438         return ret_val;
439 }
440
441 DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) {
442         int             row_count;
443         DataRange       *ret_val;
444         Data            *dta;
445         string          fname;
446         Store           *store;
447
448         ret_val = NULL;
449         fname   = get_file_name(device_id,
450                                 date,
451                                 period_type_param,
452                                 MAX);
453         if (store_data == NULL) {
454                 if (access(fname.c_str(), R_OK) == 0) {
455                         load(fname);
456                 }
457         }
458         if (store_data != NULL) {
459                 row_count       = store_data->get_count();
460                 if (row_count > 0) {
461                         ret_val = new DataRange();
462                         dta     = store_data->get(0);
463                         ret_val->add(dta);
464                         delete(dta);
465                 }
466         }
467         if (ret_val == NULL) {
468                 switch(period_type_param) {
469                         case PERIOD_YEARLY:
470                         case PERIOD_MONTHLY: {
471                                         Data            *cur_data;
472                                         Data            *res_data;
473                                         Date            *cur_date;
474                                         Date            *max_date;
475                                         int             ii;
476                                         int             cnt;
477                                         int             val_cnt;
478                                         DataRange       *dr;
479
480                                         cur_date        = date->clone();
481                                         max_date        = date->clone();
482                                         if (period_type_param == PERIOD_YEARLY) {
483                                                 max_date->next_year();
484                                         }
485                                         else {
486                                                 max_date->next_month();
487                                         }
488                                         cur_data        = NULL;
489                                         res_data        = NULL;
490                                         cnt             = 0;
491                                         while(cur_date->before(max_date)) {
492                                                 if (period_type_param == PERIOD_YEARLY) {
493                                                         store   = new StoreCache(device_id, cur_date);
494                                                         dr      = store->get_max(PERIOD_MONTHLY);
495                                                 }
496                                                 else {
497                                                         store   = new StoreDay(device_id, cur_date);
498                                                         dr      = store->get_max(PERIOD_DAILY);
499                                                 }
500                                                 if (dr != NULL) {
501                                                         cur_data        = dr->get_first();
502                                                         if (cur_data != NULL) {
503                                                                 cnt++;
504                                                                 if (res_data == NULL) {
505                                                                         res_data        = cur_data;
506                                                                 }
507                                                                 else {
508                                                                         val_cnt = res_data->get_value_count();
509                                                                         int changed = 0;
510                                                                         for (ii = 0; ii < val_cnt; ii++) {
511                                                                                 if (cur_data->value_arr[ii] > res_data->value_arr[ii]) {
512                                                                                         res_data->value_arr[ii] = cur_data->value_arr[ii];
513                                                                                         changed = 1;
514                                                                                 }
515                                                                         }
516                                                                         if (changed == 1) {
517                                                                                 Date new_date;
518
519                                                                                 new_date        = cur_data->get_date();
520                                                                                 res_data->set_date(&new_date);
521                                                                         }
522                                                                         delete(cur_data);
523                                                                 }
524                                                         }
525                                                         delete(dr);
526                                                 }
527                                                 delete(store);
528                                                 if (period_type_param == PERIOD_YEARLY) {
529                                                         cur_date->next_month();
530                                                 }
531                                                 else {
532                                                         cur_date->next_day();
533                                                 }
534                                         }
535                                         if ((res_data != NULL) &&
536                                             (cnt > 0)) {
537                                                 ret_val = new DataRange(res_data);
538                                                 save(fname, ret_val, 4);
539                                                 delete(res_data);
540                                         }
541                                         delete(cur_date);
542                                         delete(max_date);
543                                 }
544                                 break;
545                         case PERIOD_DAILY:
546                         case PERIOD_HOURLY:
547                         case PERIOD_MINUTELY:
548                         case PERIOD_SECONDLY:
549                                 store   = new StoreDay(device_id, date);
550                                 ret_val = store->get_max(period_type_param);
551                                 if ((period_type_param != PERIOD_MINUTELY) ||
552                                     (period_type_param != PERIOD_SECONDLY)) {
553                                         // no need cache second or minute data
554                                         save(fname, ret_val, 4);
555                                 }
556                                 delete(store);
557                                 break;
558                 }
559         }
560         return ret_val;
561 }
562
563 DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) {
564         int             row_count;
565         DataRange       *ret_val;
566         Data            *dta;
567         string          fname;
568         Store           *store;
569
570         ret_val = NULL;
571         fname   = get_file_name(device_id,
572                                 date,
573                                 period_type_param,
574                                 MIN);
575         if (store_data == NULL) {
576                 if (access(fname.c_str(), R_OK) == 0) {
577                         load(fname);
578                 }
579         }
580         if (store_data != NULL) {
581                 row_count       = store_data->get_count();
582                 if (row_count > 0) {
583                         ret_val = new DataRange();
584                         dta     = store_data->get(0);
585                         ret_val->add(dta);
586                         delete(dta);
587                 }
588         }
589         if (ret_val == NULL) {
590                 switch(period_type_param) {
591                         case PERIOD_YEARLY:
592                         case PERIOD_MONTHLY: {
593                                         Data            *cur_data;
594                                         Data            *res_data;
595                                         Date            *cur_date;
596                                         Date            *max_date;
597                                         int             ii;
598                                         int             cnt;
599                                         int             val_cnt;
600                                         DataRange       *dr;
601
602                                         cur_date        = date->clone();
603                                         max_date        = date->clone();
604                                         if (period_type_param == PERIOD_YEARLY) {
605                                                 max_date->next_year();
606                                         }
607                                         else {
608                                                 max_date->next_month();
609                                         }
610                                         cur_data        = NULL;
611                                         res_data        = NULL;
612                                         cnt             = 0;
613                                         while(cur_date->before(max_date)) {
614                                                 if (period_type_param == PERIOD_YEARLY) {
615                                                         store   = new StoreCache(device_id, cur_date);
616                                                         dr      = store->get_min(PERIOD_MONTHLY);
617                                                 }
618                                                 else {
619                                                         store   = new StoreDay(device_id, cur_date);
620                                                         dr      = store->get_min(PERIOD_DAILY);
621                                                 }
622                                                 if (dr != NULL) {
623                                                         cur_data        = dr->get_first();
624                                                         if (cur_data != NULL) {
625                                                                 cnt++;
626                                                                 if (res_data == NULL) {
627                                                                         res_data        = cur_data;
628                                                                 }
629                                                                 else {
630                                                                         val_cnt = res_data->get_value_count();
631                                                                         int changed = 0;
632                                                                         for (ii = 0; ii < val_cnt; ii++) {
633                                                                                 if (cur_data->value_arr[ii] < res_data->value_arr[ii]) {
634                                                                                         res_data->value_arr[ii] = cur_data->value_arr[ii];
635                                                                                         changed = 1;
636                                                                                 }
637                                                                         }
638                                                                         if (changed == 1) {
639                                                                                 Date new_date;
640
641                                                                                 new_date        = cur_data->get_date();
642                                                                                 res_data->set_date(&new_date);
643                                                                         }
644                                                                         delete(cur_data);
645                                                                 }
646                                                         }
647                                                         delete(dr);
648                                                 }
649                                                 delete(store);
650                                                 if (period_type_param == PERIOD_YEARLY) {
651                                                         cur_date->next_month();
652                                                 }
653                                                 else {
654                                                         cur_date->next_day();
655                                                 }
656                                         }
657                                         if ((res_data != NULL) &&
658                                             (cnt > 0)) {
659                                                 ret_val = new DataRange(res_data);
660                                                 save(fname, ret_val, 4);
661                                                 delete(res_data);
662                                         }
663                                         delete(cur_date);
664                                         delete(max_date);
665                                 }
666                                 break;
667                         case PERIOD_DAILY:
668                         case PERIOD_HOURLY:
669                         case PERIOD_MINUTELY:
670                         case PERIOD_SECONDLY:
671                                 store   = new StoreDay(device_id, date);
672                                 ret_val = store->get_min(period_type_param);
673                                 if ((period_type_param != PERIOD_MINUTELY) ||
674                                     (period_type_param != PERIOD_SECONDLY)) {
675                                         // no need cache second or minute data
676                                         save(fname, ret_val, 4);
677                                 }
678                                 delete(store);
679                                 break;
680                 }
681         }
682         return ret_val;
683 }
684
685 void StoreCache::save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param) {
686         string          line;
687         Data            *data;
688         ofstream        *ostream;
689         int             ii;
690         int             cnt;
691
692         cnt     = datarange_param->get_count();
693         ostream =  NULL;
694         //log_info("[%s] cacheing %d data values.\n", device_id.c_str(), cnt);
695         ostream = W1Util::open_for_writing(fname_param.c_str());
696         if ((ostream != NULL) &&
697             (ostream->is_open() == true)) {
698                 // TODO: add mutex to protect string_list while it's read and emptied
699                 for(ii = 0; ii < cnt; ii++) {
700                         data    = datarange_param->get(ii);
701                         if (data != NULL) {
702                                 line    = data->to_string(decimal_count_param);
703                                 if (line.length() > 0) {
704                                         *ostream << line << endl;
705                                 }
706                                 delete(data);
707                         }
708                 }
709         }
710         else {
711                 log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), fname_param.c_str());
712         }
713         if (ostream != NULL) {
714                 ostream->close();
715                 delete(ostream);
716         }
717 }
718
719 /**
720  * Find oldest data in certain year
721  */
722 Data *StoreCache::get_year_oldest_data() {
723         Data            *ret_val;
724         char            buffer[30];
725         DeviceData      *dta_finder;
726         string          str;
727
728         dta_finder      = new DeviceData(device_id);
729         snprintf(buffer, 30, "%d", date->year);
730         str.append(buffer);
731         ret_val         = dta_finder->find_oldest_data(str);
732         delete(dta_finder);
733         return ret_val;
734 }
735
736 /**
737  * Find newest data in certain year
738  */
739 Data *StoreCache::get_year_newest_data() {
740         Data            *ret_val;
741         char            buffer[30];
742         DeviceData      *dta_finder;
743         string          str;
744
745         dta_finder      = new DeviceData(device_id);
746         snprintf(buffer, 30, "%d", date->year);
747         str.append(buffer);
748         ret_val         = dta_finder->find_newest_data(str);
749         delete(dta_finder);
750         return ret_val;
751 }