]> pilppa.org Git - lib1wire.git/blobdiff - src/StoreCache.cc
Added support for cacheing monthly data.
[lib1wire.git] / src / StoreCache.cc
index 68a9f58dd5ed898dc4360b694a5bc835c4fc946e..3fc9c4b0aad1a95fcd23d1b160ac6855cbaa04d5 100644 (file)
@@ -18,12 +18,6 @@ using namespace w1;
 
 StoreCache::StoreCache(string device_id_param,
                Date *date_time_param): Store(device_id_param, date_time_param) {
-/*
-       store_fname     = get_file_name(device_id_param,
-                               date_time_param,
-                               period_type_param,
-                               calc_type_param);
-*/
 }
 
 StoreCache::~StoreCache() {
@@ -37,13 +31,22 @@ string StoreCache::get_dir_name(string device_id_param,
        char    buffer[30];
        string  bd_name;
 
-       snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
        bd_name = DeviceConfig::get_base_dir_name();
        bd_name = W1Util::concat_paths(bd_name, CACHE_DIR_NAME);
        bd_name = W1Util::concat_paths(bd_name, device_id_param);
        bd_name = W1Util::concat_paths(bd_name, SUMMARY_PERIOD_NAMES_ARRAY[period_type_param]);
        bd_name = W1Util::concat_paths(bd_name, CALCULATION_TYPE_NAMES_ARRAY[calc_type_param]);
-       ret_val = bd_name + "/" + buffer;
+       if (period_type_param == PERIOD_YEARLY) {
+               ret_val = bd_name;
+       }
+       else if (period_type_param == PERIOD_MONTHLY) {
+               snprintf(buffer, 30, "%d", date_time_param->year);
+               ret_val = bd_name + "/" + buffer;
+       }
+       else {
+               snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
+               ret_val = bd_name + "/" + buffer;
+       }
        return ret_val;
 }
 
@@ -55,10 +58,20 @@ string StoreCache::get_file_name(string device_id_param,
        string  fname;
        char    buffer[30];
 
-       snprintf(buffer, 30, "%d-%02d-%02d",
-               date_time_param->year,
-               date_time_param->month,
-               date_time_param->day);
+       if (period_type_param == PERIOD_YEARLY) {
+               snprintf(buffer, 30, "%d", date_time_param->year);
+       }
+       else if (period_type_param == PERIOD_MONTHLY) {
+               snprintf(buffer, 30, "%d-%02d",
+                       date_time_param->year,
+                       date_time_param->month);
+       }
+       else {
+               snprintf(buffer, 30, "%d-%02d-%02d",
+                       date_time_param->year,
+                       date_time_param->month,
+                       date_time_param->day);
+       }
        fname   = buffer;
        fname   = fname + DATAFILE_SUFFIX;
        ret_val = get_dir_name(device_id_param, date_time_param, period_type_param, calc_type_param);
@@ -93,10 +106,71 @@ DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) {
                }
        }
        if (ret_val == NULL) {
-               store   = new StoreDay(device_id, date);
-               ret_val = store->get_mean(period_type_param);
-               save(fname, ret_val, 4);
-               delete(store);
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                               break;
+                       case PERIOD_MONTHLY: {
+                                       Data            *cur_data;
+                                       Data            *res_data;
+                                       Date            *cur_date;
+                                       Date            *max_date;
+                                       int             ii;
+                                       int             cnt;
+                                       int             val_cnt;
+                                       DataRange       *dr;
+
+                                       cur_date        = date->clone();
+                                       max_date        = date->clone();
+                                       max_date->next_month();
+                                       cur_data        = NULL;
+                                       res_data        = NULL;
+                                       cnt             = 0;
+                                       while(cur_date->before(max_date)) {
+                                               store   = new StoreDay(device_id, cur_date);
+                                               dr      = store->get_mean(PERIOD_DAILY);
+                                               if (dr != NULL) {
+                                                       cur_data        = dr->get_first();
+                                                       if (cur_data != NULL) {
+                                                               cnt++;
+                                                               if (res_data == NULL) {
+                                                                       res_data        = cur_data;
+                                                               }
+                                                               else {
+                                                                       val_cnt = res_data->get_value_count();
+                                                                       for (ii = 0; ii < val_cnt; ii++) {
+                                                                               res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
+                                                                       }
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       delete(dr);
+                                               }
+                                               delete(store);
+                                               cur_date->next_day();
+                                       }
+                                       if ((res_data != NULL) &&
+                                           (cnt > 0)) {
+                                               for (ii = 0; ii < val_cnt; ii++) {
+                                                       res_data->value_arr[ii] = res_data->value_arr[ii] / cnt;
+                                               }
+                                               ret_val = new DataRange(res_data);
+                                               save(fname, ret_val, 4);
+                                               delete(res_data);
+                                       }
+                                       delete(cur_date);
+                                       delete(max_date);
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_mean(period_type_param);
+                               save(fname, ret_val, 4);
+                               delete(store);
+                               break;
+               }
        }
        return ret_val;
 }
@@ -112,7 +186,7 @@ DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) {
        fname   = get_file_name(device_id,
                                date,
                                period_type_param,
-                               MEAN);
+                               SUM);
        if (store_data == NULL) {
                if (access(fname.c_str(), R_OK) == 0) {
                        load(fname);
@@ -128,10 +202,68 @@ DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) {
                }
        }
        if (ret_val == NULL) {
-               store   = new StoreDay(device_id, date);
-               ret_val = store->get_sum(period_type_param);
-               save(fname, ret_val, 4);
-               delete(store);
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                               break;
+                       case PERIOD_MONTHLY: {
+                                       Data            *cur_data;
+                                       Data            *res_data;
+                                       Date            *cur_date;
+                                       Date            *max_date;
+                                       int             ii;
+                                       int             cnt;
+                                       int             val_cnt;
+                                       DataRange       *dr;
+
+                                       cur_date        = date->clone();
+                                       max_date        = date->clone();
+                                       max_date->next_month();
+                                       cur_data        = NULL;
+                                       res_data        = NULL;
+                                       cnt             = 0;
+                                       while(cur_date->before(max_date)) {
+                                               store   = new StoreDay(device_id, cur_date);
+                                               dr      = store->get_sum(PERIOD_DAILY);
+                                               if (dr != NULL) {
+                                                       cur_data        = dr->get_first();
+                                                       if (cur_data != NULL) {
+                                                               cnt++;
+                                                               if (res_data == NULL) {
+                                                                       res_data        = cur_data;
+                                                               }
+                                                               else {
+                                                                       val_cnt = res_data->get_value_count();
+                                                                       for (ii = 0; ii < val_cnt; ii++) {
+                                                                               res_data->value_arr[ii] = res_data->value_arr[ii] + cur_data->value_arr[ii];
+                                                                       }
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       delete(dr);
+                                               }
+                                               delete(store);
+                                               cur_date->next_day();
+                                       }
+                                       if ((res_data != NULL) &&
+                                           (cnt > 0)) {
+                                               ret_val = new DataRange(res_data);
+                                               save(fname, ret_val, 4);
+                                               delete(res_data);
+                                       }
+                                       delete(cur_date);
+                                       delete(max_date);
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_sum(period_type_param);
+                               save(fname, ret_val, 4);
+                               delete(store);
+                               break;
+               }
        }
        return ret_val;
 }
@@ -147,7 +279,7 @@ DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) {
        fname   = get_file_name(device_id,
                                date,
                                period_type_param,
-                               MEAN);
+                               DELTA);
        if (store_data == NULL) {
                if (access(fname.c_str(), R_OK) == 0) {
                        // read from cache file
@@ -164,10 +296,73 @@ DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) {
                }
        }
        if (ret_val == NULL) {
-               store   = new StoreDay(device_id, date);
-               ret_val = store->get_delta(period_type_param);
-               save(fname, ret_val, 4);
-               delete(store);
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                               break;
+                       case PERIOD_MONTHLY: {
+                                       Data    *first_data;
+                                       Data    *last_data;
+                                       Data    *cur_data;
+                                       Date    *cur_date;
+                                       Date    *limit_date;
+                                       int     ii;
+                                       int     cnt;
+
+                                       cur_date                = date->clone();
+                                       limit_date      = date->clone();
+                                       limit_date->next_month();
+                                       first_data      = NULL;
+                                       last_data       = NULL;
+                                       while(cur_date->before(limit_date)) {
+                                               store   = new StoreDay(device_id, cur_date);
+                                               if (first_data == NULL) {
+                                                       cur_data        = store->get_oldest_data();
+                                                       if (cur_data != NULL) {
+                                                               first_data      = cur_data->clone();
+                                                               last_data       = cur_data->clone();
+                                                               delete(cur_data);
+                                                       }
+                                               }
+                                               cur_data        = store->get_newest_data();
+                                               if (cur_data != NULL) {
+                                                       if (last_data != NULL) {
+                                                               delete(last_data);
+                                                       }
+                                                       last_data       = cur_data;
+                                               }
+                                               delete(store);
+                                               cur_date->next_day();
+                                       }
+                                       delete(cur_date);
+                                       delete(limit_date);
+                                       if (first_data != NULL) {
+                                               if (last_data == NULL) {
+                                                       last_data       = first_data->clone();
+                                               }
+                                               cnt     = last_data->get_value_count();
+                                               for (ii = 0; ii < cnt; ii++) {
+                                                       last_data->value_arr[ii]        = last_data->value_arr[ii] - first_data->value_arr[ii];
+                                               }
+                                               cur_date        = first_data->get_date().clone();
+                                               last_data->set_date(cur_date);
+                                               delete(cur_date);
+                                               ret_val = new DataRange(last_data);
+                                               delete(first_data);
+                                               delete(last_data);
+                                               save(fname, ret_val, 4);
+                                       }
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_delta(period_type_param);
+                               save(fname, ret_val, 4);
+                               delete(store);
+                               break;
+               }
        }
        return ret_val;
 }
@@ -183,7 +378,7 @@ DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) {
        fname   = get_file_name(device_id,
                                date,
                                period_type_param,
-                               MEAN);
+                               MAX);
        if (store_data == NULL) {
                if (access(fname.c_str(), R_OK) == 0) {
                        load(fname);
@@ -199,10 +394,78 @@ DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) {
                }
        }
        if (ret_val == NULL) {
-               store   = new StoreDay(device_id, date);
-               ret_val = store->get_max(period_type_param);
-               save(fname, ret_val, 4);
-               delete(store);
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                               break;
+                       case PERIOD_MONTHLY: {
+                                       Data            *cur_data;
+                                       Data            *res_data;
+                                       Date            *cur_date;
+                                       Date            *max_date;
+                                       int             ii;
+                                       int             cnt;
+                                       int             val_cnt;
+                                       DataRange       *dr;
+
+                                       cur_date        = date->clone();
+                                       max_date        = date->clone();
+                                       max_date->next_month();
+                                       cur_data        = NULL;
+                                       res_data        = NULL;
+                                       cnt             = 0;
+                                       while(cur_date->before(max_date)) {
+                                               store   = new StoreDay(device_id, cur_date);
+                                               dr      = store->get_max(PERIOD_DAILY);
+                                               if (dr != NULL) {
+                                                       cur_data        = dr->get_first();
+                                                       if (cur_data != NULL) {
+                                                               cnt++;
+                                                               if (res_data == NULL) {
+                                                                       res_data        = cur_data;
+                                                               }
+                                                               else {
+                                                                       val_cnt = res_data->get_value_count();
+                                                                       int changed = 0;
+                                                                       for (ii = 0; ii < val_cnt; ii++) {
+                                                                               if (cur_data->value_arr[ii] > res_data->value_arr[ii]) {
+                                                                                       res_data->value_arr[ii] = cur_data->value_arr[ii];
+                                                                                       changed = 1;
+                                                                               }
+                                                                       }
+                                                                       if (changed == 1) {
+                                                                               Date new_date;
+
+                                                                               new_date        = cur_data->get_date();
+                                                                               res_data->set_date(&new_date);
+                                                                       }
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       delete(dr);
+                                               }
+                                               delete(store);
+                                               cur_date->next_day();
+                                       }
+                                       if ((res_data != NULL) &&
+                                           (cnt > 0)) {
+                                               ret_val = new DataRange(res_data);
+                                               save(fname, ret_val, 4);
+                                               delete(res_data);
+                                       }
+                                       delete(cur_date);
+                                       delete(max_date);
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_max(period_type_param);
+                               save(fname, ret_val, 4);
+                               delete(store);
+                               break;
+               }
        }
        return ret_val;
 }
@@ -218,7 +481,7 @@ DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) {
        fname   = get_file_name(device_id,
                                date,
                                period_type_param,
-                               MEAN);
+                               MIN);
        if (store_data == NULL) {
                if (access(fname.c_str(), R_OK) == 0) {
                        load(fname);
@@ -234,10 +497,78 @@ DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) {
                }
        }
        if (ret_val == NULL) {
-               store   = new StoreDay(device_id, date);
-               ret_val = store->get_min(period_type_param);
-               save(fname, ret_val, 4);
-               delete(store);
+               switch(period_type_param) {
+                       case PERIOD_YEARLY:
+                               break;
+                       case PERIOD_MONTHLY: {
+                                       Data            *cur_data;
+                                       Data            *res_data;
+                                       Date            *cur_date;
+                                       Date            *max_date;
+                                       int             ii;
+                                       int             cnt;
+                                       int             val_cnt;
+                                       DataRange       *dr;
+
+                                       cur_date        = date->clone();
+                                       max_date        = date->clone();
+                                       max_date->next_month();
+                                       cur_data        = NULL;
+                                       res_data        = NULL;
+                                       cnt             = 0;
+                                       while(cur_date->before(max_date)) {
+                                               store   = new StoreDay(device_id, cur_date);
+                                               dr      = store->get_min(PERIOD_DAILY);
+                                               if (dr != NULL) {
+                                                       cur_data        = dr->get_first();
+                                                       if (cur_data != NULL) {
+                                                               cnt++;
+                                                               if (res_data == NULL) {
+                                                                       res_data        = cur_data;
+                                                               }
+                                                               else {
+                                                                       val_cnt = res_data->get_value_count();
+                                                                       int changed = 0;
+                                                                       for (ii = 0; ii < val_cnt; ii++) {
+                                                                               if (cur_data->value_arr[ii] < res_data->value_arr[ii]) {
+                                                                                       res_data->value_arr[ii] = cur_data->value_arr[ii];
+                                                                                       changed = 1;
+                                                                               }
+                                                                       }
+                                                                       if (changed == 1) {
+                                                                               Date new_date;
+
+                                                                               new_date        = cur_data->get_date();
+                                                                               res_data->set_date(&new_date);
+                                                                       }
+                                                                       delete(cur_data);
+                                                               }
+                                                       }
+                                                       delete(dr);
+                                               }
+                                               delete(store);
+                                               cur_date->next_day();
+                                       }
+                                       if ((res_data != NULL) &&
+                                           (cnt > 0)) {
+                                               ret_val = new DataRange(res_data);
+                                               save(fname, ret_val, 4);
+                                               delete(res_data);
+                                       }
+                                       delete(cur_date);
+                                       delete(max_date);
+                               }
+                               break;
+                       case PERIOD_DAILY:
+                       case PERIOD_HOURLY:
+                       case PERIOD_MINUTELY:
+                       case PERIOD_SECONDLY:
+                               store   = new StoreDay(device_id, date);
+                               ret_val = store->get_min(period_type_param);
+                               save(fname, ret_val, 4);
+                               delete(store);
+                               break;
+               }
        }
        return ret_val;
 }