4 * Created on: Jan 6, 2011
10 #include "StoreCache.hh"
11 #include "StoreDay.hh"
12 #include "DeviceConfig.hh"
19 StoreCache::StoreCache(string device_id_param,
20 Date *date_time_param): Store(device_id_param, date_time_param) {
23 StoreCache::~StoreCache() {
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) {
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) {
42 else if (period_type_param == PERIOD_MONTHLY) {
43 snprintf(buffer, 30, "%d", date_time_param->year);
44 ret_val = bd_name + "/" + buffer;
47 snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
48 ret_val = bd_name + "/" + buffer;
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) {
61 if (period_type_param == PERIOD_YEARLY) {
62 snprintf(buffer, 30, "%d", date_time_param->year);
64 else if (period_type_param == PERIOD_MONTHLY) {
65 snprintf(buffer, 30, "%d-%02d",
66 date_time_param->year,
67 date_time_param->month);
70 snprintf(buffer, 30, "%d-%02d-%02d",
71 date_time_param->year,
72 date_time_param->month,
73 date_time_param->day);
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);
82 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) {
112 case PERIOD_MONTHLY: {
122 cur_date = date->clone();
123 max_date = date->clone();
124 max_date->next_month();
128 while(cur_date->before(max_date)) {
129 store = new StoreDay(device_id, cur_date);
130 dr = store->get_mean(PERIOD_DAILY);
132 cur_data = dr->get_first();
133 if (cur_data != NULL) {
135 if (res_data == NULL) {
139 val_cnt = res_data->get_value_count();
140 for (ii = 0; ii < val_cnt; ii++) {
141 res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
149 cur_date->next_day();
151 if ((res_data != NULL) &&
153 for (ii = 0; ii < val_cnt; ii++) {
154 res_data->value_arr[ii] = res_data->value_arr[ii] / cnt;
156 ret_val = new DataRange(res_data);
157 save(fname, ret_val, 4);
166 case PERIOD_MINUTELY:
167 case PERIOD_SECONDLY:
168 store = new StoreDay(device_id, date);
169 ret_val = store->get_mean(period_type_param);
170 save(fname, ret_val, 4);
178 DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) {
186 fname = get_file_name(device_id,
190 if (store_data == NULL) {
191 if (access(fname.c_str(), R_OK) == 0) {
195 if (store_data != NULL) {
196 row_count = store_data->get_count();
198 ret_val = new DataRange();
199 dta = store_data->get(0);
204 if (ret_val == NULL) {
205 switch(period_type_param) {
208 case PERIOD_MONTHLY: {
218 cur_date = date->clone();
219 max_date = date->clone();
220 max_date->next_month();
224 while(cur_date->before(max_date)) {
225 store = new StoreDay(device_id, cur_date);
226 dr = store->get_sum(PERIOD_DAILY);
228 cur_data = dr->get_first();
229 if (cur_data != NULL) {
231 if (res_data == NULL) {
235 val_cnt = res_data->get_value_count();
236 for (ii = 0; ii < val_cnt; ii++) {
237 res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
245 cur_date->next_day();
247 if ((res_data != NULL) &&
249 ret_val = new DataRange(res_data);
250 save(fname, ret_val, 4);
259 case PERIOD_MINUTELY:
260 case PERIOD_SECONDLY:
261 store = new StoreDay(device_id, date);
262 ret_val = store->get_sum(period_type_param);
263 save(fname, ret_val, 4);
271 DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) {
279 fname = get_file_name(device_id,
283 if (store_data == NULL) {
284 if (access(fname.c_str(), R_OK) == 0) {
285 // read from cache file
289 if (store_data != NULL) {
290 row_count = store_data->get_count();
292 ret_val = new DataRange();
293 dta = store_data->get(0);
298 if (ret_val == NULL) {
299 switch(period_type_param) {
302 case PERIOD_MONTHLY: {
311 cur_date = date->clone();
312 limit_date = date->clone();
313 limit_date->next_month();
316 while(cur_date->before(limit_date)) {
317 store = new StoreDay(device_id, cur_date);
318 if (first_data == NULL) {
319 cur_data = store->get_oldest_data();
320 if (cur_data != NULL) {
321 first_data = cur_data->clone();
322 last_data = cur_data->clone();
326 cur_data = store->get_newest_data();
327 if (cur_data != NULL) {
328 if (last_data != NULL) {
331 last_data = cur_data;
334 cur_date->next_day();
338 if (first_data != NULL) {
339 if (last_data == NULL) {
340 last_data = first_data->clone();
342 cnt = last_data->get_value_count();
343 for (ii = 0; ii < cnt; ii++) {
344 last_data->value_arr[ii] = last_data->value_arr[ii] - first_data->value_arr[ii];
346 cur_date = first_data->get_date().clone();
347 last_data->set_date(cur_date);
349 ret_val = new DataRange(last_data);
352 save(fname, ret_val, 4);
358 case PERIOD_MINUTELY:
359 case PERIOD_SECONDLY:
360 store = new StoreDay(device_id, date);
361 ret_val = store->get_delta(period_type_param);
362 save(fname, ret_val, 4);
370 DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) {
378 fname = get_file_name(device_id,
382 if (store_data == NULL) {
383 if (access(fname.c_str(), R_OK) == 0) {
387 if (store_data != NULL) {
388 row_count = store_data->get_count();
390 ret_val = new DataRange();
391 dta = store_data->get(0);
396 if (ret_val == NULL) {
397 switch(period_type_param) {
400 case PERIOD_MONTHLY: {
410 cur_date = date->clone();
411 max_date = date->clone();
412 max_date->next_month();
416 while(cur_date->before(max_date)) {
417 store = new StoreDay(device_id, cur_date);
418 dr = store->get_max(PERIOD_DAILY);
420 cur_data = dr->get_first();
421 if (cur_data != NULL) {
423 if (res_data == NULL) {
427 val_cnt = res_data->get_value_count();
429 for (ii = 0; ii < val_cnt; ii++) {
430 if (cur_data->value_arr[ii] > res_data->value_arr[ii]) {
431 res_data->value_arr[ii] = cur_data->value_arr[ii];
438 new_date = cur_data->get_date();
439 res_data->set_date(&new_date);
447 cur_date->next_day();
449 if ((res_data != NULL) &&
451 ret_val = new DataRange(res_data);
452 save(fname, ret_val, 4);
461 case PERIOD_MINUTELY:
462 case PERIOD_SECONDLY:
463 store = new StoreDay(device_id, date);
464 ret_val = store->get_max(period_type_param);
465 save(fname, ret_val, 4);
473 DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) {
481 fname = get_file_name(device_id,
485 if (store_data == NULL) {
486 if (access(fname.c_str(), R_OK) == 0) {
490 if (store_data != NULL) {
491 row_count = store_data->get_count();
493 ret_val = new DataRange();
494 dta = store_data->get(0);
499 if (ret_val == NULL) {
500 switch(period_type_param) {
503 case PERIOD_MONTHLY: {
513 cur_date = date->clone();
514 max_date = date->clone();
515 max_date->next_month();
519 while(cur_date->before(max_date)) {
520 store = new StoreDay(device_id, cur_date);
521 dr = store->get_min(PERIOD_DAILY);
523 cur_data = dr->get_first();
524 if (cur_data != NULL) {
526 if (res_data == NULL) {
530 val_cnt = res_data->get_value_count();
532 for (ii = 0; ii < val_cnt; ii++) {
533 if (cur_data->value_arr[ii] < res_data->value_arr[ii]) {
534 res_data->value_arr[ii] = cur_data->value_arr[ii];
541 new_date = cur_data->get_date();
542 res_data->set_date(&new_date);
550 cur_date->next_day();
552 if ((res_data != NULL) &&
554 ret_val = new DataRange(res_data);
555 save(fname, ret_val, 4);
564 case PERIOD_MINUTELY:
565 case PERIOD_SECONDLY:
566 store = new StoreDay(device_id, date);
567 ret_val = store->get_min(period_type_param);
568 save(fname, ret_val, 4);
576 void StoreCache::save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param) {
583 cnt = datarange_param->get_count();
585 log_info("[%s] cacheing %d data values.\n", device_id.c_str(), cnt);
586 ostream = W1Util::open_for_writing(fname_param.c_str());
587 if ((ostream != NULL) &&
588 (ostream->is_open() == true)) {
589 // TODO: add mutex to protect string_list while it's read and emptied
590 for(ii = 0; ii < cnt; ii++) {
591 data = datarange_param->get(ii);
593 line = data->to_string(decimal_count_param);
594 if (line.length() > 0) {
595 *ostream << line << endl;
602 log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), fname_param.c_str());
604 if (ostream != NULL) {