From: Mika Laitio Date: Tue, 14 Aug 2012 22:45:36 +0000 (+0300) Subject: Data read optimizations X-Git-Url: http://pilppa.org/gitweb/?p=libplp.git;a=commitdiff_plain;h=fb1be129d4304d68e42f3e30710968a0899e5482 Data read optimizations Check the existence of year and month folders when scanning the daily data. This reduces a lot of read cycles in cases that there months of holes without data between the first and last data available for certain device. Signed-off-by: Mika Laitio --- diff --git a/src/DataReader.cc b/src/DataReader.cc index e6f184a..c1dfb48 100644 --- a/src/DataReader.cc +++ b/src/DataReader.cc @@ -194,11 +194,15 @@ DataRange *DataReader::get_summary(Date *date_param, ret_val->printout(); } else { - log_error("Could not read data log for device: %s\n", device_id.c_str()); + log_error("%s: Could not read data log for device %s. Data not found.\n", + date_param->to_string().c_str(), + device_id.c_str()); } } else { - log_error("Could not read data log for device: %s\n", device_id.c_str()); + log_error("%s: Could not read data log for device: %s. Memory allocation error..\n", + date_param->to_string().c_str(), + device_id.c_str()); } delete(store); return ret_val; @@ -229,15 +233,17 @@ DataRange *DataReader::get_yearly_summary(Date *start_date, ret_val = NULL; date = start_date->clone(); while(date->before_or_equal_year(end_date)) { - data = get_yearly_summary(date); - if (data != NULL) { - if (ret_val == NULL) { - ret_val = new DataRange(data); - } - else { - ret_val->add(data); + if (StoreDay::exist_in_year(device_id, date, false)) { + data = get_yearly_summary(date); + if (data != NULL) { + if (ret_val == NULL) { + ret_val = new DataRange(data); + } + else { + ret_val->add(data); + } + delete(data); } - delete(data); } date->next_year(); } @@ -270,17 +276,19 @@ DataRange *DataReader::get_monthly_summary(Date *start_date, ret_val = NULL; date = start_date->clone(); while(date->before_or_equal_month(end_date)) { - data = get_monthly_summary(date); - if (data != NULL) { - if (ret_val == NULL) { - ret_val = new DataRange(data); - } - else { - ret_val->add(data); + if (StoreDay::exist_in_month(device_id, date, false)) { + data = get_monthly_summary(date); + if (data != NULL) { + if (ret_val == NULL) { + ret_val = new DataRange(data); + } + else { + ret_val->add(data); + } + delete(data); } - delete(data); + date->next_month(); } - date->next_month(); } delete(date); return ret_val; @@ -340,15 +348,17 @@ DataRange *DataReader::get_daily_summary(Date *start_date, ret_val = NULL; date = start_date->clone(); while(date->before_or_equal_day(end_date)) { - data = get_daily_summary(date); - if (data != NULL) { - if (ret_val == NULL) { - ret_val = new DataRange(data); - } - else { - ret_val->add(data); + if (StoreDay::exist(device_id, date, false)) { + data = get_daily_summary(date); + if (data != NULL) { + if (ret_val == NULL) { + ret_val = new DataRange(data); + } + else { + ret_val->add(data); + } + delete(data); } - delete(data); } date->next_day(); } diff --git a/src/DataReader.hh b/src/DataReader.hh index b544242..3fe8c3b 100644 --- a/src/DataReader.hh +++ b/src/DataReader.hh @@ -18,6 +18,9 @@ #include namespace plp { + /** + * DataReader is able to read old data from the device. + */ class DataReader { public: DataReader(std::string device_id); diff --git a/src/Date.cc b/src/Date.cc index 368fafa..e831477 100644 --- a/src/Date.cc +++ b/src/Date.cc @@ -243,6 +243,24 @@ void Date::next_hour() { } } +bool Date::is_last_day_of_month() { + bool ret_val; + int days_in_month; + + days_in_month = -1; + if ((month > 0) && + (month <= 12)) { + days_in_month = CONST__DAYS_PER_MONTH[month - 1]; + if ((month == 2) && + (is_leap_year() == true)) { + days_in_month = 29; + } + } + ret_val = (day == days_in_month); + //log_debug("ret_val: %d", ret_val); + return ret_val; +} + void Date::next_day() { if ((month > 0) && (month <= 12)) { diff --git a/src/Date.hh b/src/Date.hh index 21b6bbe..ee4afb6 100644 --- a/src/Date.hh +++ b/src/Date.hh @@ -23,6 +23,7 @@ namespace plp { virtual ~Date(); void printout(); bool is_leap_year(); + bool is_last_day_of_month(); void next_second(); void next_min(); void next_hour(); diff --git a/src/DeviceData.cc b/src/DeviceData.cc index 59aa0ad..55bf71d 100644 --- a/src/DeviceData.cc +++ b/src/DeviceData.cc @@ -13,6 +13,7 @@ using namespace std; using namespace plp; DeviceData::DeviceData(string id_param, string type_param) : Device(id_param, type_param) { + _latest_data = NULL; } DeviceData::DeviceData(string id_param, diff --git a/src/FileUtil.cc b/src/FileUtil.cc index 1a45e89..8b905e6 100644 --- a/src/FileUtil.cc +++ b/src/FileUtil.cc @@ -122,7 +122,8 @@ bool FileUtil::mkdirs(const char *path) { return ret_val; } -bool FileUtil::file_exist(const char *file_name_with_path, bool writable) { +bool FileUtil::file_exist(const char *file_name_with_path, + bool writable) { bool ret_val; int acl_mode; @@ -141,6 +142,43 @@ bool FileUtil::file_exist(const char *file_name_with_path, bool writable) { return ret_val; } +bool FileUtil::dir_exist(const char *dir_name_with_path, + bool writable) { + bool ret_val; + struct stat st; + bool is_dir; + + ret_val = false; + if (stat(dir_name_with_path, &st) == 0) { + is_dir = S_ISDIR(st.st_mode); + if (is_dir == true) { + if (writable == false) { + // check only the read permission + ret_val = ((st.st_mode) & S_IRUSR); + + } + else { + // check also the write permission + ret_val = ((st.st_mode) & S_IWUSR); + } +/* + int acl_mode; + if (writable == true) { + acl_mode = W_OK; + } + else { + acl_mode = R_OK; + } + if (dir_name_with_path != NULL) { + if (access(dir_name_with_path, acl_mode) == 0) { + } + } +*/ + } + } + return ret_val; +} + bool FileUtil::mkfile(const char *file_name_with_path, bool writable) { bool ret_val; string path_name; diff --git a/src/FileUtil.hh b/src/FileUtil.hh index 50b3ddd..6bf6c73 100644 --- a/src/FileUtil.hh +++ b/src/FileUtil.hh @@ -35,6 +35,7 @@ namespace plp { * Check whether file exist with specified access rights */ static bool file_exist(const char *file_name_with_path, bool writable); + static bool dir_exist(const char *dir_name_with_path, bool writable); static std::ofstream *open_for_writing(const char *path); }; } diff --git a/src/SensorDevice.hh b/src/SensorDevice.hh index b683034..852c870 100644 --- a/src/SensorDevice.hh +++ b/src/SensorDevice.hh @@ -16,12 +16,24 @@ using namespace plp; namespace plp { + /** + * This class defines methods for Device which can return and collect data. + */ class SensorDevice : public Device { public: SensorDevice(std::string id_param, std::string type_param) : Device(id_param, type_param) {} virtual ~SensorDevice() {} - virtual const DataReader *get_device_data() = 0; + /* + * Returns DataReader class for the device. + */ + virtual const DataReader *get_datareader() = 0; + /** + * Returns the unit used by the device data. + */ virtual string get_unit() = 0; + /* + * Returns latest data that is available for the device. + */ virtual plp::Data *get_data() = 0; }; } diff --git a/src/StoreCache.cc b/src/StoreCache.cc index 0d62d77..d95c9fb 100644 --- a/src/StoreCache.cc +++ b/src/StoreCache.cc @@ -154,14 +154,24 @@ DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) { res_data = NULL; cnt = 0; val_cnt = 0; + dr = NULL; while(cur_date->before(max_date)) { if (period_type_param == PERIOD_YEARLY) { store = new StoreCache(device_id, cur_date); dr = store->get_mean(PERIOD_MONTHLY); } else { - store = new StoreDay(device_id, cur_date); - dr = store->get_mean(PERIOD_DAILY); + if (StoreDay::exist(device_id, cur_date, false)) { + store = new StoreDay(device_id, cur_date); + dr = store->get_mean(PERIOD_DAILY); + } + if (dr == NULL) { + // data not found for that day, try to find next date containing data + StoreDay::get_next_date_with_data(device_id, + cur_date, + max_date); + continue; + } } if (dr != NULL) { cur_data = dr->get_first(); @@ -204,12 +214,14 @@ DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) { case PERIOD_DAILY: case PERIOD_HOURLY: case PERIOD_MINUTELY: - case PERIOD_SECONDLY: { + case PERIOD_SECONDLY: + if (StoreDay::exist(device_id, date, false)) { StoreDay *store; store = new StoreDay(device_id, date); ret_val = store->get_mean(period_type_param); - if ((period_type_param != PERIOD_MINUTELY) || + if ((ret_val != NULL) && + (period_type_param != PERIOD_MINUTELY) && (period_type_param != PERIOD_SECONDLY)) { // no need cache second or minute data save(fname, ret_val, 4); @@ -272,8 +284,17 @@ DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) { dr = store->get_sum(PERIOD_MONTHLY); } else { - store = new StoreDay(device_id, cur_date); - dr = store->get_sum(PERIOD_DAILY); + if (StoreDay::exist(device_id, cur_date, false)) { + store = new StoreDay(device_id, cur_date); + dr = store->get_sum(PERIOD_DAILY); + } + if (dr == NULL) { + // data not found for that day, try to find next date containing data + StoreDay::get_next_date_with_data(device_id, + cur_date, + max_date); + continue; + } } if (dr != NULL) { cur_data = dr->get_first(); @@ -314,14 +335,17 @@ DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) { case PERIOD_HOURLY: case PERIOD_MINUTELY: case PERIOD_SECONDLY: - store = new StoreDay(device_id, date); - ret_val = store->get_sum(period_type_param); - if ((period_type_param != PERIOD_MINUTELY) || - (period_type_param != PERIOD_SECONDLY)) { - // no need cache second or minute data - save(fname, ret_val, 4); + if (StoreDay::exist(device_id, date, false)) { + store = new StoreDay(device_id, date); + ret_val = store->get_sum(period_type_param); + if ((ret_val != NULL) && + (period_type_param != PERIOD_MINUTELY) && + (period_type_param != PERIOD_SECONDLY)) { + // no need cache second or minute data + save(fname, ret_val, 4); + } + delete(store); } - delete(store); break; } } @@ -388,37 +412,47 @@ DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) { Data *last_data; Data *cur_data; Date *cur_date; - Date *limit_date; + Date *max_date; int ii; int cnt; cur_date = date->clone(); - limit_date = date->clone(); - limit_date->next_month(); + max_date = date->clone(); + max_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(); + while(cur_date->before(max_date)) { + if (StoreDay::exist(device_id, + cur_date, + false)) { + 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_latest_data(); if (cur_data != NULL) { - first_data = cur_data->clone(); - last_data = cur_data->clone(); - delete(cur_data); + if (last_data != NULL) { + delete(last_data); + } + last_data = cur_data; } + delete(store); + cur_date->next_day(); } - cur_data = store->get_latest_data(); - if (cur_data != NULL) { - if (last_data != NULL) { - delete(last_data); - } - last_data = cur_data; + else { + // data not found for that day, try to find next date containing data + StoreDay::get_next_date_with_data(device_id, + cur_date, + max_date); } - delete(store); - cur_date->next_day(); } delete(cur_date); - delete(limit_date); + delete(max_date); if (first_data != NULL) { if (last_data == NULL) { last_data = first_data->clone(); @@ -441,14 +475,16 @@ DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) { case PERIOD_HOURLY: case PERIOD_MINUTELY: case PERIOD_SECONDLY: - store = new StoreDay(device_id, date); - ret_val = store->get_delta(period_type_param); - if ((period_type_param != PERIOD_MINUTELY) || - (period_type_param != PERIOD_SECONDLY)) { - // no need cache second or minute data - save(fname, ret_val, 4); + if (StoreDay::exist(device_id, date, false)) { + store = new StoreDay(device_id, date); + ret_val = store->get_delta(period_type_param); + if ((period_type_param != PERIOD_MINUTELY) || + (period_type_param != PERIOD_SECONDLY)) { + // no need cache second or minute data + save(fname, ret_val, 4); + } + delete(store); } - delete(store); break; } } @@ -505,8 +541,16 @@ DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) { dr = store->get_max(PERIOD_MONTHLY); } else { - store = new StoreDay(device_id, cur_date); - dr = store->get_max(PERIOD_DAILY); + if (StoreDay::exist(device_id, cur_date, false)) { + store = new StoreDay(device_id, cur_date); + dr = store->get_max(PERIOD_DAILY); + } + else { + StoreDay::get_next_date_with_data(device_id, + cur_date, + max_date); + continue; + } } if (dr != NULL) { cur_data = dr->get_first(); @@ -557,14 +601,16 @@ DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) { case PERIOD_HOURLY: case PERIOD_MINUTELY: case PERIOD_SECONDLY: - store = new StoreDay(device_id, date); - ret_val = store->get_max(period_type_param); - if ((period_type_param != PERIOD_MINUTELY) || - (period_type_param != PERIOD_SECONDLY)) { - // no need cache second or minute data - save(fname, ret_val, 4); + if (StoreDay::exist(device_id, date, false)) { + store = new StoreDay(device_id, date); + ret_val = store->get_max(period_type_param); + if ((period_type_param != PERIOD_MINUTELY) || + (period_type_param != PERIOD_SECONDLY)) { + // no need cache second or minute data + save(fname, ret_val, 4); + } + delete(store); } - delete(store); break; } } @@ -621,8 +667,16 @@ DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) { dr = store->get_min(PERIOD_MONTHLY); } else { - store = new StoreDay(device_id, cur_date); - dr = store->get_min(PERIOD_DAILY); + if (StoreDay::exist(device_id, cur_date, false)) { + store = new StoreDay(device_id, cur_date); + dr = store->get_min(PERIOD_DAILY); + } + else { + StoreDay::get_next_date_with_data(device_id, + cur_date, + max_date); + continue; + } } if (dr != NULL) { cur_data = dr->get_first(); @@ -673,14 +727,16 @@ DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) { case PERIOD_HOURLY: case PERIOD_MINUTELY: case PERIOD_SECONDLY: - store = new StoreDay(device_id, date); - ret_val = store->get_min(period_type_param); - if ((period_type_param != PERIOD_MINUTELY) || - (period_type_param != PERIOD_SECONDLY)) { - // no need cache second or minute data - save(fname, ret_val, 4); + if (StoreDay::exist(device_id, date, false)) { + store = new StoreDay(device_id, date); + ret_val = store->get_min(period_type_param); + if ((period_type_param != PERIOD_MINUTELY) || + (period_type_param != PERIOD_SECONDLY)) { + // no need cache second or minute data + save(fname, ret_val, 4); + } + delete(store); } - delete(store); break; } } @@ -721,7 +777,9 @@ void StoreCache::save(std::string fname_param, plp::DataRange *datarange_param, } } -Data *StoreCache::get_oldest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) { +Data *StoreCache::get_oldest_data(Date *date_param, + string device_id_param, + EnumSummaryPeriod period_type_param) { int size; unsigned int ii; string year_dr; @@ -789,7 +847,9 @@ Data *StoreCache::get_oldest_data(Date *date_param, string device_id_param, Enum return ret_val; } -Data *StoreCache::get_latest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) { +Data *StoreCache::get_latest_data(Date *date_param, + string device_id_param, + EnumSummaryPeriod period_type_param) { int ii; string mon_dr; vector mon_vcr; diff --git a/src/StoreDay.cc b/src/StoreDay.cc index 5d71b37..39a2300 100644 --- a/src/StoreDay.cc +++ b/src/StoreDay.cc @@ -42,7 +42,21 @@ StoreDay::~StoreDay() { } } -string StoreDay::get_dir_name(string device_id, Date *date_time_param) { +string StoreDay::get_year_dir_name(string device_id, + Date *date_time_param) { + string ret_val; + char buffer[10]; + string bd_name; + + snprintf(buffer, 10, "%d", date_time_param->year); + bd_name = DeviceConfig::get_base_dir_name(); + bd_name = FileUtil::concat_paths(bd_name, device_id); + ret_val = bd_name + "/" + buffer; + return ret_val; +} + +string StoreDay::get_dir_name(string device_id, + Date *date_time_param) { string ret_val; char buffer[30]; string bd_name; @@ -54,12 +68,18 @@ string StoreDay::get_dir_name(string device_id, Date *date_time_param) { return ret_val; } -string StoreDay::get_file_name(string device_id, Date *date_time_param) { +string StoreDay::get_file_name(string device_id, + Date *date_time_param) { string ret_val; string fname; char buffer[30]; - snprintf(buffer, 30, "%d-%02d-%02d", date_time_param->year, date_time_param->month, date_time_param->day); + 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, date_time_param); @@ -121,14 +141,47 @@ bool StoreDay::load() { return Store::load(store_fname); } -bool StoreDay::exist(string fname_param) { +bool StoreDay::exist(string fname_param, bool writable) { + bool ret_val; + ret_val = FileUtil::file_exist(fname_param.c_str(), writable); + return ret_val; +} + +bool StoreDay::exist(string dev_id_param, + Date *date, + bool writable) { + bool ret_val; + string f_name; + + f_name = get_file_name(dev_id_param, date); + ret_val = FileUtil::file_exist(f_name.c_str(), writable); + return ret_val; +} + +bool StoreDay::exist_in_month(string dev_id_param, + Date *date, + bool writable) { + string dirname; + bool ret_val; + + dirname = StoreDay::get_dir_name(dev_id_param, date); + ret_val = FileUtil::dir_exist(dirname.c_str(), writable); + return ret_val; +} + +bool StoreDay::exist_in_year(string dev_id_param, + Date *date, + bool writable) { + string dirname; bool ret_val; - ret_val = (access(fname_param.c_str(), F_OK) == 0); + + dirname = StoreDay::get_year_dir_name(dev_id_param, date); + ret_val = FileUtil::dir_exist(dirname.c_str(), writable); return ret_val; } -bool StoreDay::exist() { - return exist(store_fname); +bool StoreDay::exist(bool writable) { + return exist(store_fname, writable); } static int get_summary_period_as_freq_seconds(EnumSummaryPeriod period_type_param) { @@ -167,19 +220,22 @@ plp::DataRange *StoreDay::get_sum(EnumSummaryPeriod period_type_param) { Date date; DataRange *ret_val; int frq_sec; + bool succ; - ret_val = new DataRange(); + ret_val = NULL; calc = NULL; limit_d = NULL; frq_sec = get_summary_period_as_freq_seconds(period_type_param); if (store_data == NULL) { - load(); + succ = load(); } - if (store_data != NULL) { + if ((succ == true) && + (store_data != NULL)) { row_count = store_data->get_count(); if (row_count > 0) { col_count = store_data->get_data_item_value_count(); if (col_count > 0) { + ret_val = new DataRange(); for (ii = 0; ii < row_count; ii++) { data = store_data->get(ii); if (data != NULL) { @@ -190,27 +246,25 @@ plp::DataRange *StoreDay::get_sum(EnumSummaryPeriod period_type_param) { limit_d->sec = 0; limit_d->inc_seconds(frq_sec); } - else { - date = data->get_date(); - if ((ii <= (row_count -1)) && - ((frq_sec == -1) || (date.before(limit_d)))) { - for (jj = 0; jj < col_count; jj++) { - calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj]; - } + date = data->get_date(); + if ((ii <= (row_count -1)) && + ((frq_sec == -1) || (date.before(limit_d)))) { + for (jj = 0; jj < col_count; jj++) { + calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj]; } - if ((ii >= (row_count -1)) || - ((frq_sec != -1) && (date.before(limit_d) == false))) { - ret_val->add(calc); - delete(calc); - calc = data->clone(); - if (limit_d != NULL) { - delete(limit_d); - } - limit_d = data->get_date().clone(); - limit_d->min = 0; - limit_d->sec = 0; - limit_d->inc_seconds(frq_sec); + } + if ((ii >= (row_count -1)) || + ((frq_sec != -1) && (date.before(limit_d) == false))) { + ret_val->add(calc); + delete(calc); + calc = data->clone(); + if (limit_d != NULL) { + delete(limit_d); } + limit_d = data->get_date().clone(); + limit_d->min = 0; + limit_d->sec = 0; + limit_d->inc_seconds(frq_sec); } delete(data); } @@ -240,20 +294,23 @@ plp::DataRange *StoreDay::get_mean(EnumSummaryPeriod period_type_param) { Date date; DataRange *ret_val; int frq_sec; + bool succ; - ret_val = new DataRange(); + ret_val = NULL; calc = NULL; limit_d = NULL; d_count = 1; frq_sec = get_summary_period_as_freq_seconds(period_type_param); if (store_data == NULL) { - load(); + succ = load(); } - if (store_data != NULL) { + if ((succ == true) && + (store_data != NULL)) { row_count = store_data->get_count(); if (row_count > 0) { col_count = store_data->get_data_item_value_count(); if (col_count > 0) { + ret_val = new DataRange(); for (ii = 0; ii < row_count; ii++) { data = store_data->get(ii); if (data != NULL) { @@ -265,32 +322,30 @@ plp::DataRange *StoreDay::get_mean(EnumSummaryPeriod period_type_param) { limit_d->sec = 0; limit_d->inc_seconds(frq_sec); } - else { - date = data->get_date(); - if ((ii <= (row_count -1)) && - ((frq_sec == -1) || (date.before(limit_d)))) { - for (jj = 0; jj < col_count; jj++) { - calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj]; - } - d_count++; + date = data->get_date(); + if ((ii <= (row_count -1)) && + ((frq_sec == -1) || (date.before(limit_d)))) { + for (jj = 0; jj < col_count; jj++) { + calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj]; } - if ((ii >= (row_count -1)) || - ((frq_sec != -1) && (date.before(limit_d) == false))) { - for (jj = 0; jj < col_count; jj++) { - calc->value_arr[jj] = calc->value_arr[jj] / d_count; - } - ret_val->add(calc); - delete(calc); - d_count = 1; - calc = data->clone(); - if (limit_d != NULL) { - delete(limit_d); - } - limit_d = data->get_date().clone(); - limit_d->min = 0; - limit_d->sec = 0; - limit_d->inc_seconds(frq_sec); + d_count++; + } + if ((ii >= (row_count -1)) || + ((frq_sec != -1) && (date.before(limit_d) == false))) { + for (jj = 0; jj < col_count; jj++) { + calc->value_arr[jj] = calc->value_arr[jj] / d_count; } + ret_val->add(calc); + delete(calc); + d_count = 1; + calc = data->clone(); + if (limit_d != NULL) { + delete(limit_d); + } + limit_d = data->get_date().clone(); + limit_d->min = 0; + limit_d->sec = 0; + limit_d->inc_seconds(frq_sec); } delete(data); } @@ -320,20 +375,23 @@ plp::DataRange *StoreDay::get_delta(EnumSummaryPeriod period_type_param) { Date date; DataRange *ret_val; int frq_sec; + bool succ; - ret_val = new DataRange(); + ret_val = NULL; calc1 = NULL; calc2 = NULL; limit_d = NULL; frq_sec = get_summary_period_as_freq_seconds(period_type_param); if (store_data == NULL) { - load(); + succ = load(); } - if (store_data != NULL) { + if ((succ == true) && + (store_data != NULL)) { row_count = store_data->get_count(); if (row_count > 0) { col_count = store_data->get_data_item_value_count(); if (col_count > 0) { + ret_val = new DataRange(); for (ii = 0; ii < row_count; ii++) { data = store_data->get(ii); if (data != NULL) { @@ -348,36 +406,34 @@ plp::DataRange *StoreDay::get_delta(EnumSummaryPeriod period_type_param) { } calc2 = NULL; } - else { - date = data->get_date(); - if ((ii <= (row_count -1)) && - ((frq_sec == -1) || (date.before(limit_d)))) { - if (calc2 != NULL) { - delete(calc2); - } - calc2 = data->clone(); - } - if ((ii >= (row_count -1)) || - ((frq_sec != -1) && (date.before(limit_d) == false))) { - if (calc2 == NULL) { - calc2 = calc1->clone(); - } - for (jj = 0; jj < col_count; jj++) { - calc2->value_arr[jj] = calc2->value_arr[jj] - calc1->value_arr[jj]; - } - ret_val->add(calc2); - delete(calc1); - calc1 = data->clone(); + date = data->get_date(); + if ((ii <= (row_count -1)) && + ((frq_sec == -1) || (date.before(limit_d)))) { + if (calc2 != NULL) { delete(calc2); - calc2 = NULL; - if (limit_d != NULL) { - delete(limit_d); - } - limit_d = data->get_date().clone(); - limit_d->min = 0; - limit_d->sec = 0; - limit_d->inc_seconds(frq_sec); } + calc2 = data->clone(); + } + if ((ii >= (row_count -1)) || + ((frq_sec != -1) && (date.before(limit_d) == false))) { + if (calc2 == NULL) { + calc2 = calc1->clone(); + } + for (jj = 0; jj < col_count; jj++) { + calc2->value_arr[jj] = calc2->value_arr[jj] - calc1->value_arr[jj]; + } + ret_val->add(calc2); + delete(calc1); + calc1 = data->clone(); + delete(calc2); + calc2 = NULL; + if (limit_d != NULL) { + delete(limit_d); + } + limit_d = data->get_date().clone(); + limit_d->min = 0; + limit_d->sec = 0; + limit_d->inc_seconds(frq_sec); } delete(data); } @@ -410,19 +466,22 @@ plp::DataRange *StoreDay::get_max_or_min(EnumSummaryPeriod period_type_param, bo Date date; DataRange *ret_val; int frq_sec; + bool succ; - ret_val = new DataRange(); + ret_val = NULL; calc = NULL; limit_d = NULL; frq_sec = get_summary_period_as_freq_seconds(period_type_param); if (store_data == NULL) { - load(); + succ = load(); } - if (store_data != NULL) { + if ((succ == true) && + (store_data != NULL)) { row_count = store_data->get_count(); if (row_count > 0) { col_count = store_data->get_data_item_value_count(); if (col_count > 0) { + ret_val = new DataRange(); for (ii = 0; ii < row_count; ii++) { data = store_data->get(ii); if (data != NULL) { @@ -433,47 +492,45 @@ plp::DataRange *StoreDay::get_max_or_min(EnumSummaryPeriod period_type_param, bo limit_d->sec = 0; limit_d->inc_seconds(frq_sec); } - else { - date = data->get_date(); - if ((ii <= (row_count -1)) && - ((frq_sec == -1) || (date.before(limit_d)))) { - int changed = 0; - if (max == true) { - for (jj = 0; jj < col_count; jj++) { - if (calc->value_arr[jj] < data->value_arr[jj]) { - calc->value_arr[jj] = data->value_arr[jj]; - changed = 1; - } + date = data->get_date(); + if ((ii <= (row_count -1)) && + ((frq_sec == -1) || (date.before(limit_d)))) { + int changed = 0; + if (max == true) { + for (jj = 0; jj < col_count; jj++) { + if (calc->value_arr[jj] < data->value_arr[jj]) { + calc->value_arr[jj] = data->value_arr[jj]; + changed = 1; } } - else { - for (jj = 0; jj < col_count; jj++) { - if (data->value_arr[jj] < calc->value_arr[jj]) { - calc->value_arr[jj] = data->value_arr[jj]; - changed = 1; - } + } + else { + for (jj = 0; jj < col_count; jj++) { + if (data->value_arr[jj] < calc->value_arr[jj]) { + calc->value_arr[jj] = data->value_arr[jj]; + changed = 1; } } - if (changed == 1) { - Date new_date; + } + if (changed == 1) { + Date new_date; - new_date = data->get_date(); - calc->set_date(&new_date); - } + new_date = data->get_date(); + calc->set_date(&new_date); } - if ((ii >= (row_count -1)) || - ((frq_sec != -1) && (date.before(limit_d) == false))) { - ret_val->add(calc); - delete(calc); - calc = data->clone(); - if (limit_d != NULL) { - delete(limit_d); - } - limit_d = data->get_date().clone(); - limit_d->min = 0; - limit_d->sec = 0; - limit_d->inc_seconds(frq_sec); + } + if ((ii >= (row_count -1)) || + ((frq_sec != -1) && (date.before(limit_d) == false))) { + ret_val->add(calc); + delete(calc); + calc = data->clone(); + if (limit_d != NULL) { + delete(limit_d); } + limit_d = data->get_date().clone(); + limit_d->min = 0; + limit_d->sec = 0; + limit_d->inc_seconds(frq_sec); } delete(data); } @@ -606,3 +663,103 @@ Data *StoreDay::get_latest_data() { } return ret_val; } + +bool StoreDay::data_day_scan_days_in_month(string dev_id_param, + Date *new_date, + Date *max_date) { + bool ret_val; + string fname; + + ret_val = false; + while((ret_val == false) && + (new_date->before(max_date))) { + new_date->next_day(); + fname = get_file_name(dev_id_param, new_date); + if (exist(fname, false) == true) { + ret_val = true; + break; + } + if (new_date->is_last_day_of_month() == true) { + break; + } + } + return ret_val; +} + +bool StoreDay::data_day_scan_month_in_year(string dev_id_param, + Date *new_date, + Date *max_date) { + bool ret_val; + + ret_val = false; + // next scan months dir existence under the first year + while((ret_val == false) && + (new_date->before(max_date))) { + new_date->next_month(); + if (exist_in_month(dev_id_param, + new_date, + false)) { + ret_val = data_day_scan_days_in_month(dev_id_param, + new_date, + max_date); + if (ret_val == true) + break; + } + if (new_date->month == 12) + break; + } + return ret_val; +} + +bool StoreDay::data_day_scan_years(string dev_id_param, + Date *new_date, + Date *max_date) { + bool ret_val; + + ret_val = false; + while((ret_val == false) && + (new_date->before(max_date))) { + new_date->next_year(); + if (exist_in_year(dev_id_param, + new_date, + false)) { + ret_val = data_day_scan_month_in_year(dev_id_param, + new_date, + max_date); + if (ret_val == true) + break; + } + } + return ret_val; +} + +bool StoreDay::get_next_date_with_data(std::string dev_id_param, + plp::Date *next_date, + plp::Date *max_date) { + bool ret_val; + Date *new_date; + string fname; + string dirname; + + new_date = next_date->clone(); + // scan first dates in current month + ret_val = data_day_scan_days_in_month(dev_id_param, + new_date, + max_date); + if (ret_val == false) { + ret_val = data_day_scan_month_in_year(dev_id_param, + new_date, + max_date); + if (ret_val == false) { + ret_val = data_day_scan_years(dev_id_param, + new_date, + max_date); + } + } + if (ret_val == true) + new_date->copy(next_date); + else + max_date->copy(next_date); + delete(new_date); + return ret_val; +} diff --git a/src/StoreDay.hh b/src/StoreDay.hh index 1b416e5..dc25895 100644 --- a/src/StoreDay.hh +++ b/src/StoreDay.hh @@ -37,17 +37,63 @@ namespace plp { /* * Checks whether store file exist. */ - bool exist(); + bool exist(bool writable); + static bool exist(std::string dev_id, + plp::Date *date, + bool writable); + static bool exist_in_month(string device_id, + Date *date, + bool writable); + static bool exist_in_year(string device_id, + Date *date, + bool writable); + static bool get_next_date_with_data(std::string device_id, + plp::Date *next_date, + plp::Date *max_date); protected: std::string store_fname; bool load(); plp::DataRange *get_max_or_min(EnumSummaryPeriod period_type_param, bool max); static std::string get_dir_name(std::string device_id, plp::Date *date_time_param); + static std::string get_year_dir_name(std::string device_id, + plp::Date *date_time_param); static std::string get_file_name(std::string device_id, plp::Date *date_time_param); plp::DataRange *get_oldest_and_latest_data(std::string fname_param); - bool exist(std::string fname_param); + /** + * Check whether the given file exist and has either read or write permissions. + */ + static bool exist(std::string fname_param, bool writable); + /** + * Go through days in month to find out whether daily data file exist. + * + * If data is not found, false is returned and last scanned date is set to next_date. + * If data is found true is returned and date is set to next_date. + */ + static bool data_day_scan_days_in_month(string dev_id_param, + Date *next_date, + Date *max_date); + /** + * Go through month dir in year to find out first date with data + * after the given date. + * + * If data is not found, false is returned and last scanned date is set to next_date. + * If data is found true is returned and date is set to next_date. + */ + static bool data_day_scan_month_in_year(string dev_id_param, + Date *next_date, + Date *max_date); + /** + * Go through year and month directories to find out first date with data + * after the given date. + * + * If data is not found, false is returned and last scanned date is set to next_date. + * If data is found true is returned and date is set to next_date. + */ + static bool data_day_scan_years(string dev_id_param, + Date *next_date, + Date *max_date); }; }