]> pilppa.org Git - libplp.git/commitdiff
Data read optimizations
authorMika Laitio <lamikr@pilppa.org>
Tue, 14 Aug 2012 22:45:36 +0000 (01:45 +0300)
committerMika Laitio <lamikr@pilppa.org>
Tue, 14 Aug 2012 22:45:36 +0000 (01:45 +0300)
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 <lamikr@pilppa.org>
src/DataReader.cc
src/DataReader.hh
src/Date.cc
src/Date.hh
src/DeviceData.cc
src/FileUtil.cc
src/FileUtil.hh
src/SensorDevice.hh
src/StoreCache.cc
src/StoreDay.cc
src/StoreDay.hh

index e6f184a050637fec945d9363924ebc0a7c9a9bea..c1dfb489c65ecd51b9388e616916f437e71f64e0 100644 (file)
@@ -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();
        }
index b544242bf39e76b1fd272b9cae6a7f00f82329de..3fe8c3bcbfc430bb42efb2da4ae5d9c62f3ccf9e 100644 (file)
@@ -18,6 +18,9 @@
 #include <time.h>
 
 namespace plp {
+       /**
+        * DataReader is able to read old data from the device.
+        */
        class DataReader {
                public:
                        DataReader(std::string device_id);
index 368fafa2c12814e03089af08771ca21a06310793..e8314771a0858286ae945f8342f26bab8084b5b4 100644 (file)
@@ -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)) {
index 21b6bbeb2569c906651fca8465311b72be9c42c2..ee4afb6e730998850460abe73217d0f929ef20a0 100644 (file)
@@ -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();
index 59aa0addd0d6185e2e4fef9f9c3e809752c3937f..55bf71dd0ad0f1f459759a3dd1d0f83ebc75a37e 100644 (file)
@@ -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,
index 1a45e8942b657b4241ad1ba01597b5fcb52fb097..8b905e6729d4958dad96ff74303a83991133f3eb 100644 (file)
@@ -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;
index 50b3ddda72f5ee8594d502f579a9203d756e9c72..6bf6c7359e7fb3504e3c2cd2ff6db7bc9e54c3f3 100644 (file)
@@ -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);
        };
 }
index b6830344bfd516270392c6bc86fc0807e69ec0d5..852c8706316956ffd68729abdfbf553c6e96e081 100644 (file)
 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;
        };
 }
index 0d62d777f5ba586b89bb1e0c0466d33800c9aabe..d95c9fb0fdf72cc74610df68cc1793825f7b7427 100644 (file)
@@ -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<string>  mon_vcr;
index 5d71b37cb39ca9e0fc75a4f1d2b28c345f0bf067..39a23005f7c3314cc237fdb5f409db3130e47e33 100644 (file)
@@ -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;
+}
index 1b416e5fbb78c9c4cd782a7bf5aa58d6c2eedb97..dc2589519ab3f35c099c83fb6e86b6d8f727cc72 100644 (file)
@@ -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);
        };
 }