4 * Created on: Jan 6, 2011
10 #include "StoreCache.hh"
11 #include "StoreDay.hh"
12 #include "DeviceConfig.hh"
13 #include "DeviceData.hh"
20 StoreCache::StoreCache(string device_id_param,
21 Date *date_time_param): Store(device_id_param, date_time_param) {
24 StoreCache::~StoreCache() {
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) {
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) {
43 else if (period_type_param == PERIOD_MONTHLY) {
44 snprintf(buffer, 30, "%d", date_time_param->year);
45 ret_val = bd_name + "/" + buffer;
48 snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
49 ret_val = bd_name + "/" + buffer;
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) {
62 if (period_type_param == PERIOD_YEARLY) {
63 snprintf(buffer, 30, "%d", date_time_param->year);
65 else if (period_type_param == PERIOD_MONTHLY) {
66 snprintf(buffer, 30, "%d-%02d",
67 date_time_param->year,
68 date_time_param->month);
71 snprintf(buffer, 30, "%d-%02d-%02d",
72 date_time_param->year,
73 date_time_param->month,
74 date_time_param->day);
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);
83 DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) {
90 fname = get_file_name(device_id,
94 if (store_data == NULL) {
95 if (access(fname.c_str(), R_OK) == 0) {
99 if (store_data != NULL) {
100 row_count = store_data->get_count();
102 ret_val = new DataRange();
103 dta = store_data->get(0);
108 if (ret_val == NULL) {
109 switch(period_type_param) {
123 cur_date = date->clone();
124 max_date = date->clone();
125 if (period_type_param == PERIOD_YEARLY) {
126 max_date->next_year();
129 max_date->next_month();
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);
140 store = new StoreDay(device_id, cur_date);
141 dr = store->get_mean(PERIOD_DAILY);
144 cur_data = dr->get_first();
145 if (cur_data != NULL) {
147 if (res_data == NULL) {
149 val_cnt = res_data->get_value_count();
152 for (ii = 0; ii < val_cnt; ii++) {
153 res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
161 if (period_type_param == PERIOD_YEARLY) {
162 cur_date->next_month();
165 cur_date->next_day();
168 if ((res_data != NULL) &&
170 for (ii = 0; ii < val_cnt; ii++) {
171 res_data->value_arr[ii] = res_data->value_arr[ii] / cnt;
173 ret_val = new DataRange(res_data);
174 save(fname, ret_val, 4);
183 case PERIOD_MINUTELY:
184 case PERIOD_SECONDLY: {
187 store = new StoreDay(device_id, date);
188 ret_val = store->get_mean(period_type_param);
189 save(fname, ret_val, 4);
198 DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) {
206 fname = get_file_name(device_id,
210 if (store_data == NULL) {
211 if (access(fname.c_str(), R_OK) == 0) {
215 if (store_data != NULL) {
216 row_count = store_data->get_count();
218 ret_val = new DataRange();
219 dta = store_data->get(0);
224 if (ret_val == NULL) {
225 switch(period_type_param) {
227 case PERIOD_MONTHLY: {
237 cur_date = date->clone();
238 max_date = date->clone();
239 if (period_type_param == PERIOD_YEARLY) {
240 max_date->next_year();
243 max_date->next_month();
248 while(cur_date->before(max_date)) {
249 if (period_type_param == PERIOD_YEARLY) {
250 store = new StoreCache(device_id, cur_date);
251 dr = store->get_sum(PERIOD_MONTHLY);
254 store = new StoreDay(device_id, cur_date);
255 dr = store->get_sum(PERIOD_DAILY);
258 cur_data = dr->get_first();
259 if (cur_data != NULL) {
261 if (res_data == NULL) {
265 val_cnt = res_data->get_value_count();
266 for (ii = 0; ii < val_cnt; ii++) {
267 res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
275 if (period_type_param == PERIOD_YEARLY) {
276 cur_date->next_month();
279 cur_date->next_day();
282 if ((res_data != NULL) &&
284 ret_val = new DataRange(res_data);
285 save(fname, ret_val, 4);
294 case PERIOD_MINUTELY:
295 case PERIOD_SECONDLY:
296 store = new StoreDay(device_id, date);
297 ret_val = store->get_sum(period_type_param);
298 save(fname, ret_val, 4);
306 DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) {
314 fname = get_file_name(device_id,
318 if (store_data == NULL) {
319 if (access(fname.c_str(), R_OK) == 0) {
320 // read from cache file
324 if (store_data != NULL) {
325 row_count = store_data->get_count();
327 ret_val = new DataRange();
328 dta = store_data->get(0);
333 if (ret_val == NULL) {
334 switch(period_type_param) {
335 case PERIOD_YEARLY: {
341 first_data = get_year_oldest_data();
342 if (first_data != NULL) {
343 last_data = get_year_newest_data();
344 if (last_data != NULL) {
345 ret_val = new DataRange();
346 cnt = last_data->get_value_count();
347 for (ii = 0; ii < cnt; ii++) {
348 last_data->value_arr[ii] = last_data->value_arr[ii] - first_data->value_arr[ii];
350 ret_val->add(last_data);
354 save(fname, ret_val, 4);
357 log_error("Could not read first or last data item from device %s for year: %d", device_id.c_str(), date->year);
361 case PERIOD_MONTHLY: {
370 cur_date = date->clone();
371 limit_date = date->clone();
372 limit_date->next_month();
375 while(cur_date->before(limit_date)) {
376 store = new StoreDay(device_id, cur_date);
377 if (first_data == NULL) {
378 cur_data = store->get_oldest_data();
379 if (cur_data != NULL) {
380 first_data = cur_data->clone();
381 last_data = cur_data->clone();
385 cur_data = store->get_newest_data();
386 if (cur_data != NULL) {
387 if (last_data != NULL) {
390 last_data = cur_data;
393 cur_date->next_day();
397 if (first_data != NULL) {
398 if (last_data == NULL) {
399 last_data = first_data->clone();
401 cnt = last_data->get_value_count();
402 for (ii = 0; ii < cnt; ii++) {
403 last_data->value_arr[ii] = last_data->value_arr[ii] - first_data->value_arr[ii];
405 cur_date = first_data->get_date().clone();
406 last_data->set_date(cur_date);
408 ret_val = new DataRange(last_data);
411 save(fname, ret_val, 4);
417 case PERIOD_MINUTELY:
418 case PERIOD_SECONDLY:
419 store = new StoreDay(device_id, date);
420 ret_val = store->get_delta(period_type_param);
421 save(fname, ret_val, 4);
429 DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) {
437 fname = get_file_name(device_id,
441 if (store_data == NULL) {
442 if (access(fname.c_str(), R_OK) == 0) {
446 if (store_data != NULL) {
447 row_count = store_data->get_count();
449 ret_val = new DataRange();
450 dta = store_data->get(0);
455 if (ret_val == NULL) {
456 switch(period_type_param) {
458 case PERIOD_MONTHLY: {
468 cur_date = date->clone();
469 max_date = date->clone();
470 if (period_type_param == PERIOD_YEARLY) {
471 max_date->next_year();
474 max_date->next_month();
479 while(cur_date->before(max_date)) {
480 if (period_type_param == PERIOD_YEARLY) {
481 store = new StoreCache(device_id, cur_date);
482 dr = store->get_max(PERIOD_MONTHLY);
485 store = new StoreDay(device_id, cur_date);
486 dr = store->get_max(PERIOD_DAILY);
489 cur_data = dr->get_first();
490 if (cur_data != NULL) {
492 if (res_data == NULL) {
496 val_cnt = res_data->get_value_count();
498 for (ii = 0; ii < val_cnt; ii++) {
499 if (cur_data->value_arr[ii] > res_data->value_arr[ii]) {
500 res_data->value_arr[ii] = cur_data->value_arr[ii];
507 new_date = cur_data->get_date();
508 res_data->set_date(&new_date);
516 if (period_type_param == PERIOD_YEARLY) {
517 cur_date->next_month();
520 cur_date->next_day();
523 if ((res_data != NULL) &&
525 ret_val = new DataRange(res_data);
526 save(fname, ret_val, 4);
535 case PERIOD_MINUTELY:
536 case PERIOD_SECONDLY:
537 store = new StoreDay(device_id, date);
538 ret_val = store->get_max(period_type_param);
539 save(fname, ret_val, 4);
547 DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) {
555 fname = get_file_name(device_id,
559 if (store_data == NULL) {
560 if (access(fname.c_str(), R_OK) == 0) {
564 if (store_data != NULL) {
565 row_count = store_data->get_count();
567 ret_val = new DataRange();
568 dta = store_data->get(0);
573 if (ret_val == NULL) {
574 switch(period_type_param) {
576 case PERIOD_MONTHLY: {
586 cur_date = date->clone();
587 max_date = date->clone();
588 if (period_type_param == PERIOD_YEARLY) {
589 max_date->next_year();
592 max_date->next_month();
597 while(cur_date->before(max_date)) {
598 if (period_type_param == PERIOD_YEARLY) {
599 store = new StoreCache(device_id, cur_date);
600 dr = store->get_min(PERIOD_MONTHLY);
603 store = new StoreDay(device_id, cur_date);
604 dr = store->get_min(PERIOD_DAILY);
607 cur_data = dr->get_first();
608 if (cur_data != NULL) {
610 if (res_data == NULL) {
614 val_cnt = res_data->get_value_count();
616 for (ii = 0; ii < val_cnt; ii++) {
617 if (cur_data->value_arr[ii] < res_data->value_arr[ii]) {
618 res_data->value_arr[ii] = cur_data->value_arr[ii];
625 new_date = cur_data->get_date();
626 res_data->set_date(&new_date);
634 if (period_type_param == PERIOD_YEARLY) {
635 cur_date->next_month();
638 cur_date->next_day();
641 if ((res_data != NULL) &&
643 ret_val = new DataRange(res_data);
644 save(fname, ret_val, 4);
653 case PERIOD_MINUTELY:
654 case PERIOD_SECONDLY:
655 store = new StoreDay(device_id, date);
656 ret_val = store->get_min(period_type_param);
657 save(fname, ret_val, 4);
665 void StoreCache::save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param) {
672 cnt = datarange_param->get_count();
674 //log_info("[%s] cacheing %d data values.\n", device_id.c_str(), cnt);
675 ostream = W1Util::open_for_writing(fname_param.c_str());
676 if ((ostream != NULL) &&
677 (ostream->is_open() == true)) {
678 // TODO: add mutex to protect string_list while it's read and emptied
679 for(ii = 0; ii < cnt; ii++) {
680 data = datarange_param->get(ii);
682 line = data->to_string(decimal_count_param);
683 if (line.length() > 0) {
684 *ostream << line << endl;
691 log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), fname_param.c_str());
693 if (ostream != NULL) {
700 * Find oldest data in certain year
702 Data *StoreCache::get_year_oldest_data() {
705 DeviceData *dta_finder;
708 dta_finder = new DeviceData(device_id);
709 snprintf(buffer, 30, "%d", date->year);
711 ret_val = dta_finder->find_oldest_data(str);
717 * Find newest data in certain year
719 Data *StoreCache::get_year_newest_data() {
722 DeviceData *dta_finder;
725 dta_finder = new DeviceData(device_id);
726 snprintf(buffer, 30, "%d", date->year);
728 ret_val = dta_finder->find_newest_data(str);