]> pilppa.org Git - lib1wire.git/commitdiff
Optimization for year and monthly data calculation.
authorMika Laitio <lamikr@pilppa.org>
Wed, 26 Jan 2011 18:50:18 +0000 (20:50 +0200)
committerMika Laitio <lamikr@pilppa.org>
Wed, 26 Jan 2011 18:50:18 +0000 (20:50 +0200)
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 <lamikr@pilppa.org>
src/Date.cc
src/Date.hh
src/DeviceData.cc
src/DeviceData.hh
src/Store.cc
src/StoreCache.cc
src/StoreCache.hh
src/W1CounterDevice.cc
src/W1Util.cc

index e45b544fc6073d40ba431f2c6eeb0d1693cc4edf..a93c0cd21b7e382573f7fb6dae07ea82d05e6cfa 100644 (file)
@@ -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();
        }
 }
 
index 1a578a4c96e1b77f8e0d6141a0106ef68adf558d..f218c9a952c1339a60b173b56457685e83847b2d 100644 (file)
@@ -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();
index 790bcaef7140cbbc1abf1e186cc81f87ec7dc3a4..c564377a146d747b9c051092e3ef55bae5664fa1 100644 (file)
@@ -4,6 +4,8 @@
  *  Created on: Nov 7, 2010
  *      Author: lamikr
  */
+#include <sstream>
+
 #include <dirent.h>
 #include <malloc.h>
 #include <errno.h>
@@ -22,6 +24,15 @@ using namespace w1;
 using namespace std;
 using namespace plp;
 
+template <class NumberDataType>
+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<string>  mon_vcr;
-       vector<string>  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<string> 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<string>  mon_vcr;
-       vector<string>  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<int>(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<string> 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<int>(val_int, year_name, dec);
+               date.year       = val_int;
+               ret_val         = StoreCache::get_oldest_data(&date, device_id, PERIOD_YEARLY);
        }
        return ret_val;
 }
index a85bf1476c739f7db65e7ca147be6668b7050401..1ccbb4f29b9cd8ab64e2a7463692cb2f83a1b68a 100644 (file)
@@ -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;
index a33465da51bd650d8b9d8b4801903729d90550c3..ff85260e9f8ef1d70f41abb8625998b013daa60d 100644 (file)
@@ -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;
 }
index 99dec06be54e0eda35fc37c844b04ef7d776c11a..baea07833af87b1576567b703a63bcfcbbaba40b 100644 (file)
@@ -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<string>  mon_vcr;
+       vector<string>  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<string>  mon_vcr;
+       vector<string>  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;
 }
index fdf3fe028a8391853e1ecdbedffb84b5d1dc6710..316c805f8c1a405e2f9cf0aaa62ff7c7cafd465c 100644 (file)
@@ -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);
        };
 }
 
index 82a0beda2a00e5212ee5c1a59cdc416e49b4b0cc..58e9a55ef742e5a9d9ef8e98142dc6f98b04f809 100644 (file)
@@ -61,7 +61,7 @@ vector<double> *W1CounterDevice::get_raw_data() {
        int             pos;
        int             b_cnt;
        string          val_str;
-       int             val_dbl;
+       int             val_int;
        vector<double>  *ret_val;
 
        ret_val = NULL;
@@ -77,8 +77,8 @@ vector<double> *W1CounterDevice::get_raw_data() {
                                                ret_val = new vector<double>();
                                        }
                                        val_str = val_str.substr(pos + 10);
-                                       string_to_number<int>(val_dbl, val_str, dec);
-                                       ret_val->push_back(val_dbl);
+                                       string_to_number<int>(val_int, val_str, dec);
+                                       ret_val->push_back(val_int);
                                }
                        }
                }
index b375a352494933ccb26056cbffef57c71c0dde93..a9fc351b9755a28e3cd18c17a94f693127108aea 100644 (file)
@@ -231,7 +231,7 @@ vector<string> W1Util::get_subdirectories(const string& path) {
        bool            bool_flg;
        vector<string>  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());