From 4d28d5175f0bd7f930f67b1280d998eddd21ed80 Mon Sep 17 00:00:00 2001 From: Mika Laitio Date: Wed, 26 Jan 2011 20:50:18 +0200 Subject: [PATCH] Optimization for year and monthly data calculation. Added checks for finding last data per year or per month to avoid unneccessary scanning of day-files which does not neccessarily exist. Signed-off-by: Mika Laitio --- src/Date.cc | 73 ++++++++------ src/Date.hh | 2 + src/DeviceData.cc | 87 +++++------------ src/DeviceData.hh | 2 - src/Store.cc | 3 + src/StoreCache.cc | 209 ++++++++++++++++++++++++++++++----------- src/StoreCache.hh | 6 +- src/W1CounterDevice.cc | 6 +- src/W1Util.cc | 2 +- 9 files changed, 233 insertions(+), 157 deletions(-) diff --git a/src/Date.cc b/src/Date.cc index e45b544..a93c0cd 100644 --- a/src/Date.cc +++ b/src/Date.cc @@ -212,15 +212,33 @@ bool Date::before_or_equal(Date *date2) { return ret_val; } +void Date::next_second() { + if (sec < 59) { + sec++; + } + else { + next_min(); + } +} + +void Date::next_min() { + if (min < 59) { + sec = 0; + min++; + } + else { + next_hour(); + } +} + void Date::next_hour() { - sec = 0; - min = 0; hour++; - if (hour < 0) { - hour = 0; + if (hour < 23) { + sec = 0; + min = 0; + hour++; } - if (hour >= 24) { - hour = 0; + else { next_day(); } } @@ -228,34 +246,31 @@ void Date::next_hour() { void Date::next_day() { if ((month > 0) && (month <= 12)) { - day++; - if (day > CONST__DAYS_PER_MONTH[month - 1]) { - if ((month == 2) && - (is_leap_year() == true) && - (day == 29)) { - // ok - } - else { - day = 1; - month++; - if (month > 12) { - year++; - month = 1; - } - } + if ((day < CONST__DAYS_PER_MONTH[month - 1]) || + ((month == 2) && + (is_leap_year() == true) && + (day == 28))) { + sec = 0; + min = 0; + hour = 0; + day++; + } + else { + next_month(); } } } void Date::next_month() { - sec = 0; - min = 0; - hour = 0; - day = 1; - month++; - if (month > 12) { - month = 1; - year++; + if (month < 12) { + sec = 0; + min = 0; + hour = 0; + day = 1; + month++; + } + else { + next_year(); } } diff --git a/src/Date.hh b/src/Date.hh index 1a578a4..f218c9a 100644 --- a/src/Date.hh +++ b/src/Date.hh @@ -23,6 +23,8 @@ namespace plp { virtual ~Date(); void printout(); bool is_leap_year(); + void next_second(); + void next_min(); void next_hour(); void next_day(); void next_month(); diff --git a/src/DeviceData.cc b/src/DeviceData.cc index 790bcae..c564377 100644 --- a/src/DeviceData.cc +++ b/src/DeviceData.cc @@ -4,6 +4,8 @@ * Created on: Nov 7, 2010 * Author: lamikr */ +#include + #include #include #include @@ -22,6 +24,15 @@ using namespace w1; using namespace std; using namespace plp; +template +bool string_to_number(NumberDataType& result, + const std::string& string_param, + std::ios_base& (*format)(std::ios_base&)) +{ + istringstream iss(string_param); + return !(iss >> format >> result).fail(); +} + DeviceData::DeviceData(string device_id_param) { string base_dir; @@ -40,81 +51,21 @@ DeviceData::~DeviceData() { } } -Data *DeviceData::find_newest_data(string year_name_param) { - int ii; - string mon_dr; - vector mon_vcr; - vector d_vcr; - string f_name; - StoreDay *store; - Data *ret_val; - string year_dr; - int size; - - ret_val = NULL; - year_dr = W1Util::concat_paths(device_dir, year_name_param); - mon_vcr = W1Util::get_subdirectories(year_dr); - for (ii = mon_vcr.size() - 1; ii >= 0; ii--) { - mon_dr = mon_vcr.at(ii); - mon_dr = W1Util::concat_paths(year_dr, mon_dr); - // scan data files from month dir - d_vcr = W1Util::get_data_files(mon_dr); - size = d_vcr.size(); - if (size > 0) { - f_name = d_vcr.at(size - 1); - f_name = W1Util::concat_paths(mon_dr, f_name); - store = new StoreDay(f_name); - ret_val = store->get_newest_data(); - delete(store); - break; - } - } - return ret_val; -} - Data *DeviceData::find_newest_data(vector year_name_vector_param) { string year_name; int size; Data *ret_val; + Date date; + int val_int; ret_val = NULL; size = year_name_vector_param.size(); if (size > 0) { // dirs are alphabetically sorted year_name = year_name_vector_param.at(size - 1); - ret_val = find_newest_data(year_name); - } - return ret_val; -} - -Data *DeviceData::find_oldest_data(string year_name_param) { - int size; - unsigned int ii; - string year_dr; - string mon_dr; - vector mon_vcr; - vector dta_vcr; - string f_name; - StoreDay *store; - Data *ret_val; - - ret_val = NULL; - year_dr = W1Util::concat_paths(device_dir, year_name_param); - mon_vcr = W1Util::get_subdirectories(year_dr); - for (ii = 0; ii < mon_vcr.size(); ii++) { - mon_dr = mon_vcr.at(ii); - mon_dr = W1Util::concat_paths(year_dr, mon_dr); - // scan data files from month dir - dta_vcr = W1Util::get_data_files(mon_dr); - size = dta_vcr.size(); - if (size > 0) { - f_name = dta_vcr.at(0); - f_name = W1Util::concat_paths(mon_dr, f_name); - store = new StoreDay(f_name); - ret_val = store->get_oldest_data(); - delete(store); - break; - } + string_to_number(val_int, year_name, dec); + date.year = val_int; + ret_val = StoreCache::get_newest_data(&date, device_id, PERIOD_YEARLY); } return ret_val; } @@ -123,13 +74,17 @@ Data *DeviceData::find_oldest_data(vector year_name_vector_param) { int size; string year_name; Data *ret_val; + Date date; + int val_int; ret_val = NULL; size = year_name_vector_param.size(); if (size > 0) { // dirs are alphabetically sorted year_name = year_name_vector_param.at(0); - ret_val = find_oldest_data(year_name); + string_to_number(val_int, year_name, dec); + date.year = val_int; + ret_val = StoreCache::get_oldest_data(&date, device_id, PERIOD_YEARLY); } return ret_val; } diff --git a/src/DeviceData.hh b/src/DeviceData.hh index a85bf14..1ccbb4f 100644 --- a/src/DeviceData.hh +++ b/src/DeviceData.hh @@ -48,8 +48,6 @@ namespace plp { plp::DataRange *get_hourly_summary(plp::Date *date); plp::DataRange *get_hourly_summary(plp::Date *start_date, plp::Date *end_date); plp::DataRange *get_data(plp::Date *start_date, plp::Date *end_date); - plp::Data *find_newest_data(std::string year_name_param); - plp::Data *find_oldest_data(std::string year_name_param); protected: std::string device_id; std::string device_dir; diff --git a/src/Store.cc b/src/Store.cc index a33465d..ff85260 100644 --- a/src/Store.cc +++ b/src/Store.cc @@ -72,5 +72,8 @@ bool Store::load(string fname_param) { log_error("Could not open data file: %s\n", fname_param.c_str()); } } + else { + log_error("Could not find file: %s\n", fname_param.c_str()); + } return ret_val; } diff --git a/src/StoreCache.cc b/src/StoreCache.cc index 99dec06..baea078 100644 --- a/src/StoreCache.cc +++ b/src/StoreCache.cc @@ -80,6 +80,29 @@ string StoreCache::get_file_name(string device_id_param, return ret_val; } +plp::Date *StoreCache::get_scanning_limit_date(EnumSummaryPeriod period_type_param) { + Data *cur_data;; + Date *ret_val; + + cur_data = get_newest_data(date, device_id, period_type_param); + if (cur_data != NULL) { + ret_val = cur_data->get_date().clone(); + ret_val->next_second(); + delete(cur_data); + cur_data = NULL; + } + else { + ret_val = date->clone(); + if (period_type_param == PERIOD_YEARLY) { + ret_val->next_year(); + } + else { + ret_val->next_month(); + } + } + return ret_val; +} + DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) { int row_count; DataRange *ret_val; @@ -121,13 +144,7 @@ DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) { Store *store; cur_date = date->clone(); - max_date = date->clone(); - if (period_type_param == PERIOD_YEARLY) { - max_date->next_year(); - } - else { - max_date->next_month(); - } + max_date = get_scanning_limit_date(period_type_param); cur_data = NULL; res_data = NULL; cnt = 0; @@ -239,13 +256,7 @@ DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) { DataRange *dr; cur_date = date->clone(); - max_date = date->clone(); - if (period_type_param == PERIOD_YEARLY) { - max_date->next_year(); - } - else { - max_date->next_month(); - } + max_date = get_scanning_limit_date(period_type_param); cur_data = NULL; res_data = NULL; cnt = 0; @@ -346,9 +357,9 @@ DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) { int ii; int cnt; - first_data = get_year_oldest_data(); + first_data = get_oldest_data(date, device_id, PERIOD_YEARLY); if (first_data != NULL) { - last_data = get_year_newest_data(); + last_data = get_newest_data(date, device_id, PERIOD_YEARLY); if (last_data != NULL) { ret_val = new DataRange(); cnt = last_data->get_value_count(); @@ -478,13 +489,7 @@ DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) { DataRange *dr; cur_date = date->clone(); - max_date = date->clone(); - if (period_type_param == PERIOD_YEARLY) { - max_date->next_year(); - } - else { - max_date->next_month(); - } + max_date = get_scanning_limit_date(period_type_param); cur_data = NULL; res_data = NULL; cnt = 0; @@ -600,13 +605,7 @@ DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) { DataRange *dr; cur_date = date->clone(); - max_date = date->clone(); - if (period_type_param == PERIOD_YEARLY) { - max_date->next_year(); - } - else { - max_date->next_month(); - } + max_date = get_scanning_limit_date(period_type_param); cur_data = NULL; res_data = NULL; cnt = 0; @@ -716,36 +715,138 @@ void StoreCache::save(std::string fname_param, plp::DataRange *datarange_param, } } -/** - * Find oldest data in certain year - */ -Data *StoreCache::get_year_oldest_data() { +Data *StoreCache::get_oldest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) { + int size; + unsigned int ii; + string year_dr; + string mon_dr; + vector mon_vcr; + vector dta_vcr; + string f_name; + StoreDay *store; Data *ret_val; + string device_dir; char buffer[30]; - DeviceData *dta_finder; - string str; - - dta_finder = new DeviceData(device_id); - snprintf(buffer, 30, "%d", date->year); - str.append(buffer); - ret_val = dta_finder->find_oldest_data(str); - delete(dta_finder); + string year_name; + + ret_val = NULL; + if (period_type_param == PERIOD_YEARLY) { + snprintf(buffer, 30, "%d", date_param->year); + year_name.append(buffer); + device_dir = DeviceConfig::get_base_dir_name(); + device_dir = W1Util::concat_paths(device_dir, device_id_param); + year_dr = W1Util::concat_paths(device_dir, year_name); + mon_vcr = W1Util::get_subdirectories(year_dr); + for (ii = 0; ii < mon_vcr.size(); ii++) { + mon_dr = mon_vcr.at(ii); + mon_dr = W1Util::concat_paths(year_dr, mon_dr); + // scan data files from month dir + dta_vcr = W1Util::get_data_files(mon_dr); + size = dta_vcr.size(); + if (size > 0) { + f_name = dta_vcr.at(0); + f_name = W1Util::concat_paths(mon_dr, f_name); + store = new StoreDay(f_name); + ret_val = store->get_oldest_data(); + delete(store); + break; + } + } + } + else if (period_type_param == PERIOD_MONTHLY) { + ret_val = NULL; + snprintf(buffer, 30, "%d", date_param->year); + year_name.append(buffer); + device_dir = DeviceConfig::get_base_dir_name(); + device_dir = W1Util::concat_paths(device_dir, device_id_param); + year_dr = W1Util::concat_paths(device_dir, year_name); + snprintf(buffer, 30, "%02d", date_param->month); + mon_dr.append(buffer); + mon_dr = W1Util::concat_paths(year_dr, mon_dr); + // scan data files from month dir + dta_vcr = W1Util::get_data_files(mon_dr); + size = dta_vcr.size(); + if (size > 0) { + f_name = dta_vcr.at(0); + f_name = W1Util::concat_paths(mon_dr, f_name); + store = new StoreDay(f_name); + ret_val = store->get_oldest_data(); + delete(store); + } + + } + else { + store = new StoreDay(device_id_param, date_param); + ret_val = store->get_oldest_data(); + delete(store); + } return ret_val; } -/** - * Find newest data in certain year - */ -Data *StoreCache::get_year_newest_data() { +Data *StoreCache::get_newest_data(Date *date_param, string device_id_param, EnumSummaryPeriod period_type_param) { + int ii; + string mon_dr; + vector mon_vcr; + vector dta_vcr; + string f_name; + StoreDay *store; Data *ret_val; + string year_dr; + int size; + string device_dir; char buffer[30]; - DeviceData *dta_finder; - string str; - - dta_finder = new DeviceData(device_id); - snprintf(buffer, 30, "%d", date->year); - str.append(buffer); - ret_val = dta_finder->find_newest_data(str); - delete(dta_finder); + string year_name; + + ret_val = NULL; + if (period_type_param == PERIOD_YEARLY) { + snprintf(buffer, 30, "%d", date_param->year); + year_name.append(buffer); + device_dir = DeviceConfig::get_base_dir_name(); + device_dir = W1Util::concat_paths(device_dir, device_id_param); + year_dr = W1Util::concat_paths(device_dir, year_name); + mon_vcr = W1Util::get_subdirectories(year_dr); + for (ii = mon_vcr.size() - 1; ii >= 0; ii--) { + mon_dr = mon_vcr.at(ii); + mon_dr = W1Util::concat_paths(year_dr, mon_dr); + // scan data files from month dir + dta_vcr = W1Util::get_data_files(mon_dr); + size = dta_vcr.size(); + if (size > 0) { + f_name = dta_vcr.at(size - 1); + f_name = W1Util::concat_paths(mon_dr, f_name); + store = new StoreDay(f_name); + ret_val = store->get_newest_data(); + delete(store); + break; + } + } + } + else if (period_type_param == PERIOD_MONTHLY) { + ret_val = NULL; + snprintf(buffer, 30, "%d", date_param->year); + year_name.append(buffer); + device_dir = DeviceConfig::get_base_dir_name(); + device_dir = W1Util::concat_paths(device_dir, device_id_param); + year_dr = W1Util::concat_paths(device_dir, year_name); + snprintf(buffer, 30, "%02d", date_param->month); + mon_dr.append(buffer); + mon_dr = W1Util::concat_paths(year_dr, mon_dr); + // scan data files from month dir + dta_vcr = W1Util::get_data_files(mon_dr); + size = dta_vcr.size(); + if (size > 0) { + f_name = dta_vcr.at(size - 1); + f_name = W1Util::concat_paths(mon_dr, f_name); + store = new StoreDay(f_name); + ret_val = store->get_newest_data(); + delete(store); + } + + } + else { + store = new StoreDay(device_id_param, date_param); + ret_val = store->get_newest_data(); + delete(store); + } return ret_val; } diff --git a/src/StoreCache.hh b/src/StoreCache.hh index fdf3fe0..316c805 100644 --- a/src/StoreCache.hh +++ b/src/StoreCache.hh @@ -27,9 +27,9 @@ namespace plp { plp::DataRange *get_delta(EnumSummaryPeriod period_type_param); plp::DataRange *get_max(EnumSummaryPeriod period_type_param); plp::DataRange *get_min(EnumSummaryPeriod period_type_param); + static plp::Data *get_oldest_data(plp::Date *date_param, std::string device_id_param, EnumSummaryPeriod period_type_param); + static plp::Data *get_newest_data(plp::Date *date_param, std::string device_id_param, EnumSummaryPeriod period_type_param); protected: - plp::Data *get_year_oldest_data(); - plp::Data *get_year_newest_data(); static std::string get_dir_name(std::string device_id_param, Date *date_time_param, EnumSummaryPeriod period_type_param, @@ -39,6 +39,8 @@ namespace plp { EnumSummaryPeriod period_type_param, EnumSummaryCalculationType calc_type_param); void save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param); + private: + plp::Date *get_scanning_limit_date(EnumSummaryPeriod period_type_param); }; } diff --git a/src/W1CounterDevice.cc b/src/W1CounterDevice.cc index 82a0bed..58e9a55 100644 --- a/src/W1CounterDevice.cc +++ b/src/W1CounterDevice.cc @@ -61,7 +61,7 @@ vector *W1CounterDevice::get_raw_data() { int pos; int b_cnt; string val_str; - int val_dbl; + int val_int; vector *ret_val; ret_val = NULL; @@ -77,8 +77,8 @@ vector *W1CounterDevice::get_raw_data() { ret_val = new vector(); } val_str = val_str.substr(pos + 10); - string_to_number(val_dbl, val_str, dec); - ret_val->push_back(val_dbl); + string_to_number(val_int, val_str, dec); + ret_val->push_back(val_int); } } } diff --git a/src/W1Util.cc b/src/W1Util.cc index b375a35..a9fc351 100644 --- a/src/W1Util.cc +++ b/src/W1Util.cc @@ -231,7 +231,7 @@ vector W1Util::get_subdirectories(const string& path) { bool bool_flg; vector ret_val; - log_debug("scanning path: %s\n", path.c_str()); + //log_debug("scanning path: %s\n", path.c_str()); errno = 0; if (path.empty() == false) { dir = opendir(path.c_str()); -- 2.41.0