]> pilppa.org Git - lib1wire.git/commitdiff
Started adding support for caches when reading data. Cache files for
authorMika Laitio <lamikr@pilppa.org>
Sun, 23 Jan 2011 22:23:18 +0000 (00:23 +0200)
committerMika Laitio <lamikr@pilppa.org>
Sun, 23 Jan 2011 22:23:18 +0000 (00:23 +0200)
daily data calculations works already. (Cache done during first
calculation when the cache does not yet exist.)

Cache does not yet handle situations if the daily data is updated once
the cached value has been calculated.

Memory leak fixes and api changes.

Signed-off-by: Mika Laitio <lamikr@pilppa.org>
20 files changed:
src/Data.cc
src/Data.hh
src/Date.cc
src/Date.hh
src/DeviceConfig.cc
src/DeviceConfig.hh
src/DeviceData.cc
src/DeviceData.hh
src/Factory.cc
src/Makefile.am
src/Store.cc
src/Store.hh
src/StoreCache.cc [new file with mode: 0644]
src/StoreCache.hh [new file with mode: 0644]
src/StoreDay.cc [new file with mode: 0644]
src/StoreDay.hh [new file with mode: 0644]
src/W1Configure.hh
src/W1Device.cc
src_test/test_w1_datalog_read.cc
src_test/test_w1_datalog_write.cc

index cc29d51cd733aeebbfa2f356661a9fd6ab9add4b..923def183ee6c553496022bc45eccb45c693434c 100644 (file)
@@ -142,7 +142,7 @@ Data *Data::parse_string(const string& dataline) {
 
        ii      = 0;
        ret_val = NULL;
-       log_debug("parse_string: %s\n", dataline.c_str());
+       //log_debug("parse_string: %s\n", dataline.c_str());
        while(getline(ss, item, '|')) {
                if (ii == 0) {
                        // parse date
@@ -151,7 +151,7 @@ Data *Data::parse_string(const string& dataline) {
                else if (ii >= 1) {
                        suc_flg = string_to_number<double>(val, item, dec);
                        if (suc_flg) {
-                               log_debug("adding number: %f\n", val);
+                               //log_debug("adding number: %f\n", val);
                                v.push_back(val);
                        }
                }
@@ -195,12 +195,35 @@ string Data::to_string() {
        return to_string(3);
 }
 
+DataRange::DataRange() {
+       val_matrix      = NULL;
+       column_count    = 0;
+       row_count       = 0;
+       unit            = "";
+}
+
 DataRange::DataRange(Data *data) {
        val_matrix      = NULL;
-       column_count    = data->value_arr.size();
        row_count       = 0;
-       unit            = data->get_unit();
-       add_data(data);
+       if (data != NULL) {
+               column_count    = data->value_arr.size();
+               unit            = data->get_unit();
+               add(data);
+       }
+       else {
+               column_count    = 0;
+               unit            = "";
+       }
+}
+
+DataRange::DataRange(DataRange *datarange) {
+       val_matrix      = NULL;
+       row_count       = 0;
+       column_count    = 0;
+       unit            = "";
+       if (datarange != NULL) {
+               add(datarange);
+       }
 }
 
 DataRange::DataRange(int value_count_per_data_item, string unit_param) {
@@ -224,42 +247,64 @@ DataRange::~DataRange() {
        }
 }
 
-void DataRange::add_data(Data *data) {
+void DataRange::add(Data *data) {
        int     ii;
        int     indx;
        Date    *date;
        int     cnt;
 
-       //log_debug("old row_count: %d, column_count: %d, value_arr_size: %d\n", row_count, column_count, data.value_arr.size());
-       cnt             = (row_count + 1) * column_count;
-       val_matrix      = (double *)realloc(val_matrix, cnt * sizeof(double));
-       indx            = row_count * column_count;
-       cnt             = data->value_arr.size();
-       if (cnt != column_count) {
-               log_error("Error when adding data... Invalid data item count!\n");
-               if (cnt > column_count) {
-                       cnt     = column_count;
+       if (data != NULL) {
+               if ((val_matrix == NULL) &&
+                   (column_count == 0) &&
+                   (unit.empty() == true)) {
+                       column_count    = data->value_arr.size();
+                       unit            = data->get_unit();
                }
-               else {
-                       for (ii = cnt; ii < column_count; ii++) {
-                               val_matrix[indx + ii]   = 0;
+               cnt             = (row_count + 1) * column_count;
+               val_matrix      = (double *)realloc(val_matrix, cnt * sizeof(double));
+               indx            = row_count * column_count;
+               cnt             = data->value_arr.size();
+               if (cnt != column_count) {
+                       log_error("Error when adding data... Invalid data item count!\n");
+                       if (cnt > column_count) {
+                               cnt     = column_count;
+                       }
+                       else {
+                               for (ii = cnt; ii < column_count; ii++) {
+                                       val_matrix[indx + ii]   = 0;
+                               }
                        }
                }
-       }
-       for (ii = 0; ii < cnt; ii++) {
-               val_matrix[indx + ii]   = data->value_arr[ii];
-       }
+               for (ii = 0; ii < cnt; ii++) {
+                       val_matrix[indx + ii]   = data->value_arr[ii];
+               }
 /*
-       for (int ii = 0; ii < ((row_count + 1) * column_count); ii++) {
-               log_debug("data_matrix[%d] = %f\n", ii, val_matrix[ii]);
-       }
+               for (int ii = 0; ii < ((row_count + 1) * column_count); ii++) {
+                       log_debug("data_matrix[%d] = %f\n", ii, val_matrix[ii]);
+               }
 */
-       date    = data->get_date().clone();
-       date_list.push_back(date);
-       row_count++;
+               date    = data->get_date().clone();
+               date_list.push_back(date);
+               row_count++;
+       }
+}
+
+void DataRange::add(DataRange *datarange) {
+       int     ii;
+       int     cnt;
+       Data    *dta;
+
+       if (datarange != NULL) {
+               cnt     = datarange->get_count();
+               for (ii = 0; ii < cnt; ii++) {
+                       dta     = datarange->get(ii);
+                       add(dta);
+                       delete(dta);
+               }
+       }
 }
 
-Data *DataRange::get_data(int row_index) {
+Data *DataRange::get(int row_index) {
        Data            *ret_val;
        int             start_indx;
        int             ii;
@@ -274,7 +319,7 @@ Data *DataRange::get_data(int row_index) {
                for (ii = 0; ii < column_count; ii++) {
                        //val   = val_matrix[0];
                        val     = val_matrix[start_indx + ii];
-                       log_debug("val[%d] = %f\n", (start_indx + ii), val);
+                       //log_debug("val[%d] = %f\n", (start_indx + ii), val);
                        vect.push_back(val);
                }
                date    = date_list.at(row_index);
@@ -283,26 +328,26 @@ Data *DataRange::get_data(int row_index) {
        return ret_val;
 }
 
-int DataRange::get_data_row_count() {
+int DataRange::get_count() {
        return row_count;
 }
 
-int DataRange::get_data_column_count() {
+int DataRange::get_data_item_value_count() {
        return column_count;
 }
 
-Data *DataRange::get_first_data() {
+Data *DataRange::get_first() {
        Data    *ret_val;
 
        ret_val = NULL;
        if (row_count > 0) {
-               ret_val = get_data(0);
+               ret_val = get(0);
        }
        return ret_val;
 }
 
-Data *DataRange::get_last_data() {
-       return get_data(row_count - 1);
+Data *DataRange::get_last() {
+       return get(row_count - 1);
 }
 
 void DataRange::printout() {
@@ -311,7 +356,7 @@ void DataRange::printout() {
 
        log_debug("---- DataRange, number of data items: %d\n ----", row_count);
        for (ii = 0; ii < row_count; ii++) {
-               data    = get_data(ii);
+               data    = get(ii);
                if (data != NULL) {
                        data->printout();
                        delete(data);
index 11c168d79440b8db859332a14cecb28753c8b647..fe819b53e3484474054ef4ce0bcd5a964326e7e0 100644 (file)
@@ -40,15 +40,18 @@ namespace plp {
 
        class DataRange {
                public:
+                       DataRange();
                        DataRange(Data *data);
+                       DataRange(DataRange *datarange);
                        DataRange(int item_count_per_value, std::string unit_param);
                        virtual ~DataRange();
-                       void add_data(Data *data);
-                       Data *get_data(int row_index);
-                       Data *get_first_data();
-                       Data *get_last_data();
-                       int get_data_row_count();
-                       int get_data_column_count();
+                       void add(Data *data);
+                       void add(DataRange *datarange);
+                       Data *get(int row_index);
+                       Data *get_first();
+                       Data *get_last();
+                       int get_count();
+                       int get_data_item_value_count();
                        std::string get_unit();
                        void printout();
                protected:
index d13d6d4798443fb9fd2c93875feb531289972e7e..86b2cdc82a73bd28179ef36d8e9532f6dee9b0f7 100644 (file)
@@ -121,6 +121,97 @@ bool Date::equals(Date *date2) {
        return ret_val;
 }
 
+bool Date::before_or_equal_year(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = (this->year <= date2->year);
+       return ret_val;
+}
+
+bool Date::before_or_equal_month(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (this->year < date2->month) {
+               ret_val = true;
+       }
+       else {
+               if ((this->year == date2->year) &&
+                   (this->month <= date2->month)) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal_day(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_day_string();
+               s2      = date2->to_sortable_day_string();
+               if (s1.compare(s2) <= 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal_hour(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_hour_string();
+               s2      = date2->to_sortable_hour_string();
+               if (s1.compare(s2) <= 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal_min(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_min_string();
+               s2      = date2->to_sortable_min_string();
+               if (s1.compare(s2) <= 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
+bool Date::before_or_equal(Date *date2) {
+       bool    ret_val;
+       string  s1;
+       string  s2;
+
+       ret_val = false;
+       if (date2 != NULL) {
+               s1      = this->to_sortable_string();
+               s2      = date2->to_sortable_string();
+               if (s1.compare(s2) <= 0) {
+                       ret_val = true;
+               }
+       }
+       return ret_val;
+}
+
 void Date::tomorrow() {
        if ((month > 0) &&
            (month <= 12)) {
@@ -134,7 +225,7 @@ void Date::tomorrow() {
                        else {
                                day     = 1;
                                month++;
-                               if (month == 12) {
+                               if (month > 12) {
                                        year++;
                                        month   = 1;
                                }
@@ -197,6 +288,35 @@ void Date::inc_seconds(int seconds) {
        }
 }
 
+string Date::to_sortable_day_string() {
+       char    buffer[30];
+
+
+       string  ret_val;
+
+       sprintf(buffer, "%016d%02d%02d", year, month, day);
+       ret_val = buffer;
+       return ret_val;
+}
+
+string Date::to_sortable_hour_string() {
+       char    buffer[30];
+       string  ret_val;
+
+       sprintf(buffer, "%016d%02d%02d%02d", year, month, day, hour);
+       ret_val = buffer;
+       return ret_val;
+}
+
+string Date::to_sortable_min_string() {
+       char    buffer[30];
+       string  ret_val;
+
+       sprintf(buffer, "%016d%02d%02d%02d%02d", year, month, day, hour, min);
+       ret_val = buffer;
+       return ret_val;
+}
+
 string Date::to_sortable_string() {
        char    buffer[30];
        string  ret_val;
index 3c019995683b3f61be43b1925aa74f5a42bcd9ba..2a1015ca83c707f837051d4a01f631263dde7dd6 100644 (file)
@@ -31,6 +31,12 @@ namespace plp {
                        void copy(Date *date);
                        bool before(Date *date2);
                        bool equals(Date *date2);
+                       bool before_or_equal(Date *date2);
+                       bool before_or_equal_year(Date *date2);
+                       bool before_or_equal_month(Date *date2);
+                       bool before_or_equal_day(Date *date2);
+                       bool before_or_equal_hour(Date *date2);
+                       bool before_or_equal_min(Date *date2);
                        int     year;
                        int     month;
                        int     day;
@@ -40,6 +46,9 @@ namespace plp {
                        std::string to_string();
                protected:
                        std::string to_sortable_string();
+                       std::string to_sortable_day_string();
+                       std::string to_sortable_hour_string();
+                       std::string to_sortable_min_string();
                        //static const int arr_days_per_month[];
        };
 }
index f94637cca7ab5b3e716a7d33eebfec2426cbaa0d..066a22ca838a359c7698509da5eab8ff8367c29b 100644 (file)
@@ -22,13 +22,13 @@ using namespace w1;
 string DeviceConfig::store_base_dir    = DEFAULT_STORAGE_BASE_DIR;
 
 ConfigHandle::ConfigHandle(uci_context *ctx_param, uci_package *pkg_param) {
-       ctx     = ctx_param;
-       pkg     = pkg_param;
+       _ctx    = ctx_param;
+       _pkg    = pkg_param;
 }
 
 ConfigHandle::~ConfigHandle() {
-       uci_unload(ctx, pkg);
-       uci_free_context(ctx);
+       uci_unload(_ctx, _pkg);
+       uci_free_context(_ctx);
 }
 
 DeviceConfig::DeviceConfig(string device_id_param) {
@@ -92,9 +92,9 @@ string DeviceConfig::get_cfg_value(string key) {
        string                  ret_val;
 
        if (uci_handle != NULL) {
-               section = uci_lookup_section(uci_handle->ctx, uci_handle->pkg, DEVICE_CONFIG__SECTION_NAME);
+               section = uci_lookup_section(uci_handle->_ctx, uci_handle->_pkg, DEVICE_CONFIG__SECTION_NAME);
                if (section != NULL) {
-                       option  = uci_lookup_option(uci_handle->ctx, section, key.c_str());
+                       option  = uci_lookup_option(uci_handle->_ctx, section, key.c_str());
                        switch (option->type) {
                                case UCI_TYPE_STRING:
                                        log_info("key: %s option name: %s, value: %s\n", key.c_str(), option->e.name, option->v.string);
@@ -110,8 +110,8 @@ string DeviceConfig::get_cfg_value(string key) {
 }
 
 void DeviceConfig::set_cfg_value(string key, string value) {
-       string cfg_dir;
-       string cfg_fl;
+       string  cfg_dir;
+       string  cfg_fl;
 
        cfg_dir = get_dir_name(device_id);
        cfg_fl  = DEVICE_CONFIG__FILE_NAME;
@@ -123,8 +123,8 @@ void DeviceConfig::set_cfg_value(string key, string value) {
                        value.c_str());
 }
 
-enum_summary_calculation DeviceConfig::get_summary_calculation_type() {
-       enum_summary_calculation        ret_val;
+EnumSummaryCalculationType DeviceConfig::get_summary_calculation_type() {
+       EnumSummaryCalculationType      ret_val;
 
        ret_val = MEAN;
        if (device_type.empty() == false) {
@@ -150,27 +150,29 @@ ConfigHandle *DeviceConfig::load_device_config(string device_id_param) {
                        W1Util::mkdirs(cfg_dir.c_str());
                }
                cfg_fl  = get_file_name(device_id_param);
-               ctx     = uci_alloc_context();
-               if (ctx != NULL) {
-                       log_debug("uci_set_confdir: %s\n", cfg_dir.c_str());
-                       uci_set_confdir(ctx, cfg_dir.c_str());
-                       if (access(cfg_fl.c_str(), R_OK) == 0) {
+               if (access(cfg_fl.c_str(), R_OK) == 0) {
+                       ctx     = uci_alloc_context();
+                       if (ctx != NULL) {
+                               log_debug("uci_set_confdir: %s\n", cfg_dir.c_str());
+                               uci_set_confdir(ctx, cfg_dir.c_str());
                                err_flg = uci_load(ctx, cfg_fl.c_str(), &pkg);
                                if (err_flg == UCI_OK) {
-                                       log_debug("Loaded device configuration file: %s\n.", cfg_fl.c_str());
+                                       log_debug("Loaded device configuration: %s\n.", cfg_fl.c_str());
                                        ret_val = new ConfigHandle(ctx, pkg);
                                }
                                else {
-                                       log_debug("Failed to load file: %s, err code: %d\n.", cfg_fl.c_str(), UCI_OK);
+                                       log_debug("Failed to load device configuration: %s, err code: %d\n.", cfg_fl.c_str(), UCI_OK);
                                        set_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE, "");
+                                       uci_free_context(ctx);
                                }
                        }
                        else {
-                               log_error("Failed to load device device configuration, file does not exit: %s.\n", cfg_fl.c_str());
+                               log_error("Failed to load device device configuration, memory allocation error.\n");
+                               set_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE, "");
                        }
                }
                else {
-                       log_error("Failed to load device device configuration, invalid device id: %s.\n", cfg_dir.c_str());
+                       log_error("Failed to load device device configuration, file does not exist: %s.\n", cfg_fl.c_str());
                }
        }
        return ret_val;
index 0c83811457afd332b06d63917096edb355d80ef8..107018b907ae8997b82c9d6f53acbcb7901fa6b1 100644 (file)
@@ -15,6 +15,8 @@ extern "C" {
 #include <plp/config.h>
 }
 
+#include "W1Configure.hh"
+
 #define DEVICE_CONFIG__FILE_NAME               "dev_cfg.txt"
 #define DEVICE_CONFIG__SECTION_TYPE            "device"
 #define DEVICE_CONFIG__SECTION_NAME            "base_data"
@@ -23,14 +25,12 @@ extern "C" {
 #define DEVICE_CONFIG_VALUE_KEY__NAME          "name"
 
 namespace w1 {
-       enum enum_summary_calculation {SUM, DELTA, MIN, MAX, MEAN};
-
        struct ConfigHandle {
                public:
                        ConfigHandle(uci_context *ctx_param, uci_package *pkg_param);
                        ~ConfigHandle();
-                       struct uci_context      *ctx;
-                       struct uci_package      *pkg;
+                       struct uci_context      *_ctx;
+                       struct uci_package      *_pkg;
        };
 
        class DeviceConfig {
@@ -41,7 +41,7 @@ namespace w1 {
                        static void set_base_dir_name(std::string store_param);
                        std::string get_cfg_value(std::string key);
                        void set_cfg_value(std::string key, std::string value);
-                       enum_summary_calculation get_summary_calculation_type();
+                       EnumSummaryCalculationType get_summary_calculation_type();
                private:
                        static std::string      store_base_dir;
                        std::string             device_id;
index d066bbdc3f96f9f423d0c58935b3709baae9547f..d47eb005692ef6498ee0159a572bbc4976a00532 100644 (file)
@@ -11,7 +11,8 @@
 
 #include "W1Util.hh"
 #include "DeviceData.hh"
-#include "Store.hh"
+#include "StoreDay.hh"
+#include "StoreCache.hh"
 #include "DeviceConfig.hh"
 #include "Factory.hh"
 
@@ -44,7 +45,7 @@ Data *DeviceData::find_oldest_data(vector<string> year_vector) {
        vector<string>  mon_vcr;
        vector<string>  dta_vcr;
        string          f_name;
-       Store           *store;
+       StoreDay        *store;
        Data            *ret_val;
 
        ret_val = NULL;
@@ -61,7 +62,7 @@ Data *DeviceData::find_oldest_data(vector<string> year_vector) {
                        if (dta_vcr.size() > 0) {
                                f_name  = dta_vcr.at(0);
                                f_name  = W1Util::concat_paths(mon_dr, f_name);
-                               store   = new Store(f_name);
+                               store   = new StoreDay(f_name);
                                ret_val = store->get_oldest_data();
                                delete(store);
                                break;
@@ -80,7 +81,7 @@ Data *DeviceData::find_newest_data(vector<string> year_vector) {
        string          f_name;
        Data            *ret_val;
        int             size;
-       Store           *store;
+       StoreDay                *store;
 
        ret_val = NULL;
        size    = year_vector.size();
@@ -98,7 +99,7 @@ Data *DeviceData::find_newest_data(vector<string> year_vector) {
                        if (size > 0) {
                                f_name  = d_vcr.at(size - 1);
                                f_name  = W1Util::concat_paths(mon_dr, f_name);
-                               store   = new Store(f_name);
+                               store   = new StoreDay(f_name);
                                ret_val = store->get_newest_data();
                                delete(store);
                                break;
@@ -121,7 +122,7 @@ DataRange *DeviceData::get_data_range() {
                n_data  = find_newest_data(y_list);
                if (n_data != NULL) {
                        ret_val = new DataRange(o_data);
-                       ret_val->add_data(n_data);
+                       ret_val->add(n_data);
                        delete(n_data);
                }
                delete(o_data);
@@ -129,38 +130,38 @@ DataRange *DeviceData::get_data_range() {
        return ret_val;
 }
 
-long int get_interval_type(Date *start_date,
+EnumSummaryPeriod get_period_type(Date *start_date,
                        Date *end_date) {
-       int     diff;
-       int     ret_val;
+       int                     diff;
+       EnumSummaryPeriod       ret_val;
 
-       ret_val = 0;
+       ret_val = PERIOD_YEARLY;
        diff    = end_date->year - start_date->year;
        if (diff != 0) {
-               ret_val = 0;
+               ret_val = PERIOD_YEARLY;
        }
        else {
                diff    = end_date->month - start_date->month;
                if (diff != 0) {
-                       ret_val = 1;
+                       ret_val = PERIOD_MONTHLY;
                }
                else {
                        diff    = end_date->day - start_date->day;
                        if (diff != 0) {
-                               ret_val = 2;
+                               ret_val = PERIOD_DAILY;
                        }
                        else {
                                diff    = end_date->hour - start_date->hour;
                                if (diff != 0) {
-                                       ret_val = 3;
+                                       ret_val = PERIOD_HOURLY;
                                }
                                else {
                                        diff    = end_date->min - start_date->min;
                                        if (diff != 0) {
-                                               ret_val = 4;
+                                               ret_val = PERIOD_MINUTELY;
                                        }
                                        else {
-                                               ret_val = 5;
+                                               ret_val = PERIOD_SECONDLY;
                                        }
                                }
                        }
@@ -169,45 +170,39 @@ long int get_interval_type(Date *start_date,
        return ret_val;
 }
 
-Data *DeviceData::get_daily_summary(Date *date,
-                               int calc_type) {
-       Data    *ret_val;
-       Store   *store;
-       bool    suc_flg;
-       //Store *cache_store;
+DataRange *DeviceData::get_summary(Date *date_param,
+                               EnumSummaryCalculationType calc_type_param,
+                               EnumSummaryPeriod period_type_param) {
+       DataRange       *ret_val;
+       StoreCache      *store;
 
        ret_val = NULL;
-       store   = new Store(device_id, date);
+       //store = new StoreDay(device_id, date_param);
+       store   = new StoreCache(device_id, date_param);
        if (store != NULL) {
-               suc_flg = store->load();
-               if (suc_flg == true) {
-                       switch(calc_type) {
-                               case SUM:
-                                       ret_val = store->get_sum();
-                                       break;
-                               case DELTA:
-                                       ret_val = store->get_delta();
-                                       break;
-                               case MAX:
-                                       ret_val = store->get_max();
-                                       break;
-                               case MIN:
-                                       ret_val = store->get_min();
-                                       break;
-                               case MEAN:
-                               default:
-                                       ret_val = store->get_mean();
-                                       break;
-                       }
-                       if (ret_val != NULL) {
-                               ret_val->printout();
-                       }
-                       else {
-                               log_error("Could not read data log for device: %s\n", device_id.c_str());
-                       }
+               switch(calc_type_param) {
+                       case SUM:
+                               ret_val = store->get_sum(period_type_param);
+                               break;
+                       case DELTA:
+                               ret_val = store->get_delta(period_type_param);
+                               break;
+                       case MAX:
+                               ret_val = store->get_max(period_type_param);
+                               break;
+                       case MIN:
+                               ret_val = store->get_min(period_type_param);
+                               break;
+                       case MEAN:
+                       default:
+                               ret_val = store->get_mean(period_type_param);
+                               break;
+               }
+               if (ret_val != NULL) {
+                       ret_val->printout();
                }
                else {
-                       log_error("Could not read data log for device: %s. Data file open load failed.\n", device_id.c_str());
+                       log_error("Could not read data log for device: %s\n", device_id.c_str());
                }
        }
        else {
@@ -217,8 +212,13 @@ Data *DeviceData::get_daily_summary(Date *date,
        return ret_val;
 }
 
-Data *DeviceData::get_daily_summary(Date *date) {
-       Data    *ret_val;
+DataRange *DeviceData::get_daily_summary(Date *date,
+                               EnumSummaryCalculationType calc_type_param) {
+       return get_summary(date, calc_type_param, PERIOD_DAILY);
+}
+
+DataRange *DeviceData::get_daily_summary(Date *date) {
+       DataRange       *ret_val;
 
        ret_val = get_daily_summary(date, summary_calc_type);
        return ret_val;
@@ -227,19 +227,19 @@ Data *DeviceData::get_daily_summary(Date *date) {
 DataRange *DeviceData::get_daily_summary(Date *start_date,
                                        Date *end_date) {
        DataRange       *ret_val;
-       Data            *data;
+       DataRange       *data;
        Date            *date;
 
        ret_val = NULL;
        date    = start_date->clone();
-       while(date->before(end_date)) {
+       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(data);
+                               ret_val->add(data);
                        }
                        delete(data);
                }
@@ -249,38 +249,13 @@ DataRange *DeviceData::get_daily_summary(Date *start_date,
        return ret_val;
 }
 
-vector<Data *> *DeviceData::get_hourly_summary(Date *date,
-                                       int calc_type) {
-       vector<Data *>  *ret_val;
-       Store           *store;
-
-       ret_val = NULL;
-       store   = new Store(device_id, date);
-       store->load();
-       switch(calc_type) {
-               case SUM:
-                       ret_val = store->get_sum(3600);
-                       break;
-               case DELTA:
-                       ret_val = store->get_delta(3600);
-                       break;
-               case MEAN:
-               default:
-                       ret_val = store->get_mean(3600);
-                       break;
-               case MAX:
-                       ret_val = store->get_max(3600);
-                       break;
-               case MIN:
-                       ret_val = store->get_min(3600);
-                       break;
-       }
-       delete(store);
-       return ret_val;
+DataRange *DeviceData::get_hourly_summary(Date *date,
+               EnumSummaryCalculationType calc_type_param) {
+       return get_summary(date, calc_type_param, PERIOD_HOURLY);
 }
 
-vector<Data *> *DeviceData::get_hourly_summary(Date *date) {
-       vector<Data *>  *ret_val;
+DataRange *DeviceData::get_hourly_summary(Date *date) {
+       DataRange       *ret_val;
 
        ret_val = get_hourly_summary(date, summary_calc_type);
        return ret_val;
@@ -288,24 +263,26 @@ vector<Data *> *DeviceData::get_hourly_summary(Date *date) {
 
 DataRange *DeviceData::get_hourly_summary(Date *start_date,
                                        Date *end_date) {
-       DataRange                       *ret_val;
-       vector<Data *>                  *dta_lst;
-       Data                            *data;
-       Date                            *date;
-       vector<Data *>::iterator        iter;
+       DataRange       *ret_val;
+       DataRange       *dta_lst;
+       Data            *data;
+       Date            *date;
+       int             cnt;
+       int             ii;
 
        ret_val = NULL;
        date    = start_date->clone();
-       while(date->before(end_date)) {
+       while(date->before_or_equal_hour(end_date)) {
                dta_lst = get_hourly_summary(date);
-               for(iter = dta_lst->begin(); iter != dta_lst->end(); iter++) {
-                       data    = (Data *)*iter;
+               cnt     = dta_lst->get_count();
+               for(ii = 0; ii < cnt; ii++) {
+                       data    = dta_lst->get(ii);
                        if (data != NULL) {
                                if (ret_val == NULL) {
                                        ret_val = new DataRange(data);
                                }
                                else {
-                                       ret_val->add_data(data);
+                                       ret_val->add(data);
                                }
                                delete(data);
                        }
@@ -318,33 +295,35 @@ DataRange *DeviceData::get_hourly_summary(Date *start_date,
 
 DataRange *DeviceData::get_data(Date *start_date,
                                Date *end_date) {
-       DataRange       *ret_val;
-       int             int_type;
+       DataRange               *ret_val;
+       EnumSummaryPeriod       period;
 
-       ret_val         = NULL;
+       ret_val = NULL;
        start_date->printout();
        end_date->printout();
-       int_type        = get_interval_type(start_date, end_date);
-       switch(int_type) {
-               case 0:
-                       log_debug("get yearly summary\n");
+       period  = get_period_type(start_date, end_date);
+       switch(period) {
+               case PERIOD_YEARLY:
+                       log_debug("get yearly summary: %s - %s\n", start_date->to_string().c_str(), end_date->to_string().c_str());
+                       ret_val = get_daily_summary(start_date, end_date);
                        break;
-               case 1:
+               case PERIOD_MONTHLY:
                        log_debug("get monthly summary\n");
                        ret_val = get_daily_summary(start_date, end_date);
                        break;
-               case 2:
+               case PERIOD_DAILY:
                        log_debug("get daily summary\n");
                        ret_val = get_daily_summary(start_date, end_date);
                        break;
-               case 3:
+               case PERIOD_HOURLY:
                        log_debug("get hourly summary\n");
                        ret_val = get_hourly_summary(start_date, end_date);
                        break;
-               case 4:
+               case PERIOD_MINUTELY:
                        log_debug("get minute summary data\n");
                        break;
-               case 5:
+               case PERIOD_SECONDLY:
+               default:
                        log_debug("get second summary data\n");
                        break;
        }
index eb64b0662fb2f15a0404acdb2c3c42c39944c7fc..2c1641087814119a44197f4b0ce0294968ffc903 100644 (file)
@@ -23,15 +23,15 @@ namespace w1 {
                        DeviceData(std::string device_id);
                        virtual ~DeviceData();
                        plp::DataRange *get_data_range();
-                       plp::Data *get_daily_summary(plp::Date *date, int calc_type);
+                       plp::DataRange *get_daily_summary(plp::Date *date, EnumSummaryCalculationType calc_type);
                        /**
                         * Get summary data calculated from the daily data items that is meaning full.
                         * Depending from the device type, it may be daily mean value, daily delta, highest value, etc...
                         */
-                       plp::Data *get_daily_summary(plp::Date *date);
+                       plp::DataRange *get_daily_summary(plp::Date *date);
                        plp::DataRange *get_daily_summary(plp::Date *start_date, plp::Date *end_date);
-                       std::vector<plp::Data *> *get_hourly_summary(plp::Date *date, int calc_type);
-                       std::vector<plp::Data *> *get_hourly_summary(plp::Date *date);
+                       plp::DataRange *get_hourly_summary(plp::Date *date, EnumSummaryCalculationType calc_type);
+                       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);
                protected:
@@ -39,9 +39,12 @@ namespace w1 {
                        std::string                     device_dir;
                        std::string                     device_ch_dir;
                        w1::DeviceConfig                *device_config;
-                       enum_summary_calculation        summary_calc_type;
+                       EnumSummaryCalculationType      summary_calc_type;
                        plp::Data *find_oldest_data(std::vector<std::string> year_vector);
                        plp::Data *find_newest_data(std::vector<std::string> year_vector);
+                       plp::DataRange *get_summary(plp::Date *date_param,
+                                       EnumSummaryCalculationType calc_type_param,
+                                       EnumSummaryPeriod period_type_param);
        };
 }
 
index 1ce585b003c23b8e42093696ae46ca4f4c6918f0..c8dc6949f957fe6f1c71b7e8f15338ad26d32eba 100644 (file)
@@ -42,6 +42,7 @@ W1Device *Factory::get_device(int family_code,
                        dirent *direntry_param) {
        W1Device        *ret_val;
        DeviceConfig    *config;
+       string          type;
 
        ret_val = NULL;
        switch(family_code) {
@@ -62,7 +63,6 @@ W1Device *Factory::get_device(int family_code,
                config  = get_device_config(device_id);
                if (config != NULL) {
                        // if not, create default device config
-                       string  type;
                        type    = config->get_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE);
                        if (type.empty() == true) {
                                type    = ret_val->get_device_type();
index 9a18e11d643364878484cbed3a2c21bbf9f1281d..9c6cb215c6cd06ad4c997d6783ea07270c2d15e3 100644 (file)
@@ -3,6 +3,8 @@ lib1wire_la_SOURCES = \
        Factory.cc Factory.hh \
        W1Device.cc W1Device.hh \
        Store.cc Store.hh \
+       StoreDay.cc StoreDay.hh \
+       StoreCache.cc StoreCache.hh \
        W1TemperatureSensor.cc W1TemperatureSensor.hh \
        W1CounterDevice.cc W1CounterDevice.hh \
        W1Util.cc W1Util.hh \
@@ -26,5 +28,7 @@ lib1wireinclude_HEADERS = \
        W1CounterDevice.hh \
        W1Device.hh \
        Store.hh \
+       StoreDay.hh \
+       StoreCache.hh \
        W1TemperatureSensor.hh \
        W1Util.hh
\ No newline at end of file
index 125a9063681fc16e24c3c72381cf11e4da30680d..288f7f2fec80c7e9507769aff2d463a93adf15f9 100644 (file)
@@ -1,44 +1,29 @@
 /*
  * Store.cc
  *
- *  Created on: Oct 31, 2010
+ *  Created on: Jan 20, 2011
  *      Author: lamikr
  */
-
-#include <list>
-#include <string>
 #include <fstream>
-#include <limits>
 
-#include <time.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
+#include "Store.hh"
 
 #include <plp/log.h>
 
-#include "DeviceConfig.hh"
-#include "W1Configure.hh"
-#include "Store.hh"
-#include "W1Util.hh"
-
 using namespace std;
-using namespace w1;
 using namespace plp;
 
-Store::Store(string device_id,
-               Date *date_time) {
-       store_data      = NULL;
-       range_data      = NULL;
-       store_file_name = get_file_name(device_id, date_time);
-       log_debug("data file name: %s\n", store_file_name.c_str());
-}
-
-Store::Store(string file_name_param) {
+Store::Store(string device_id_param,
+               Date *date_param) {
+       device_id       = device_id_param;
+       if (date_param != NULL) {
+               date            = date_param->clone();
+       }
+       else {
+               date    = NULL;
+       }
        store_data      = NULL;
        range_data      = NULL;
-       store_file_name = file_name_param;
 }
 
 Store::~Store() {
@@ -46,80 +31,12 @@ Store::~Store() {
                delete(store_data);
                store_data      = NULL;
        }
-}
-
-string Store::get_dir_name(string device_id, Date *date_time) {
-       string  ret_val;
-       char    buffer[30];
-       string  d_name;
-
-       d_name  = DeviceConfig::get_base_dir_name();
-       snprintf(buffer, 30, "%d/%02d", date_time->year, date_time->month);
-       ret_val = W1Util::concat_paths(d_name, device_id);
-       ret_val = ret_val + "/" + buffer;
-       return ret_val;
-}
-
-string Store::get_file_name(string device_id, Date *date_time) {
-       string  ret_val;
-       string  fname;
-       char    buffer[30];
-
-       snprintf(buffer, 30, "%d-%02d-%02d", date_time->year, date_time->month, date_time->day);
-       fname   = buffer;
-       fname   = fname + DATAFILE_SUFFIX;
-       ret_val = get_dir_name(device_id, date_time);
-       ret_val = W1Util::concat_paths(ret_val, fname);
-       return ret_val;
-}
-
-void Store::save(string device_id,
-               std::list<Data *> *data_list,
-               int dec_precision) {
-       string                  n_path;
-       string                  f_path;
-       string                  line;
-       Data                    *data;
-       ofstream                *ostream;
-       Date                    date;
-       list<Data *>::iterator  iter;
-
-       ostream =  NULL;
-       f_path  = "";
-       log_info("[%s] writing %d data values to save.\n", device_id.c_str(), data_list->size());
-       // TODO: add mutex to protect string_list while it's read and emptied
-       for(iter = data_list->begin(); iter != data_list->end(); iter++) {
-               data    = (Data *)*iter;
-               date    = data->get_date();
-               n_path  = get_file_name(device_id, &date);
-               if (n_path.compare(f_path) != 0) {
-                       if (ostream != NULL) {
-                               ostream->close();
-                               delete(ostream);
-                       }
-                       f_path  = n_path;
-                       log_info("[%s] Opening file for save: %s\n", device_id.c_str(), f_path.c_str());
-                       ostream = W1Util::open_for_writing(f_path.c_str());
-               }
-               if ((ostream != NULL) &&
-                   (ostream->is_open() == true)) {
-                       line    = data->to_string(dec_precision);
-                       if (line.length() > 0) {
-                               log_debug("storing line: %s\n", line.c_str());
-                               *ostream << line << endl;
-                       }
-               }
-               else {
-                       log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), f_path.c_str());
-               }
-       }
-       if (ostream != NULL) {
-               ostream->close();
-               delete(ostream);
+       if (date != NULL) {
+               delete(date);
        }
 }
 
-bool Store::load() {
+bool Store::load(string fname_param) {
        Data            *data;
        ifstream        in;
        string          data_str;
@@ -130,655 +47,33 @@ bool Store::load() {
                delete(store_data);
                store_data      = NULL;
        }
-       log_debug("opening file: %s\n", store_file_name.c_str());
-       in.open(store_file_name.c_str());
-       if (in.is_open() == true) {
-               while (in.eof() == false) {
-                       getline(in, data_str);
-                       if (data_str.empty() == false) {
-                               data    = Data::parse_string(data_str);
-                               if (data != NULL) {
-                                       if (store_data == NULL) {
-                                               store_data      = new DataRange(data);
-                                       }
-                                       else {
-                                               store_data->add_data(data);
-                                       }
-                                       delete(data);
-                               }
-                       }
-               }
-               ret_val = true;
-       }
-       else {
-               log_error("Could not load data from file: %s\n", store_file_name.c_str());
-       }
-       return ret_val;
-}
-
-Data *Store::get_sum() {
-       int     row_count;
-       int     col_count;
-       double  new_val;
-       int     ii;
-       int     jj;
-       Data    *data;
-       Data    *ret_val;
-       Date    date;
-
-       ret_val = NULL;
-       data    = NULL;
-       if (store_data == NULL) {
-               load();
-       }
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               log_debug("data row count: %d\n", row_count);
-               if (row_count > 0) {
-                       col_count       = store_data->get_data_column_count();
-                       log_debug("data item count per row: %d\n", col_count);
-                       ret_val         = new Data(col_count);
-                       if (col_count > 0) {
-                               for (ii = 0; ii < row_count - 1; ii++) {
-                                       data    = store_data->get_data(ii);
-                                       for (jj = 0; jj < col_count; jj++) {
-                                               new_val                 = data->value_arr[jj];
-                                               ret_val->value_arr[jj]  = ret_val->value_arr[jj] + new_val;
-                                       }
-                                       if (ii < (row_count - 2)) {
-                                               delete(data);
-                                               data    = NULL;
-                                       }
-                                       //log_debug("new val: %f, sum: %f\n", new_val, sum);
-                               }
-                       }
-                       date    = data->get_date();
-                       ret_val->set_date(&date);
-                       if (data != NULL) {
-                               delete(data);
-                       }
-               }
-       }
-       return ret_val;
-}
-
-Data *Store::get_delta() {
-       int             row_count;
-       int             col_count;
-       Data            *o_data;
-       Data            *n_data;
-       Data            *ret_val;
-       int             ii;
-       DataRange       *dr;
-       Date            date;
-
-       ret_val = NULL;
-       dr      = get_oldest_and_newest_data();
-       if (dr != NULL) {
-               row_count       = dr->get_data_row_count();
-               if (row_count == 2) {
-                       o_data          = dr->get_data(0);
-                       n_data          = dr->get_data(1);
-                       col_count       = dr->get_data_column_count();
-                       ret_val         = new Data(col_count);
-                       if (col_count > 0) {
-                               for (ii = 0; ii < col_count; ii++) {
-                                       log_debug("old_data[%d]: %f new data: %f\n", ii, o_data->value_arr[ii], n_data->value_arr[ii]);
-                                       ret_val->value_arr[ii]  = n_data->value_arr[ii] - o_data->value_arr[ii];
-                               }
-                       }
-                       date    = n_data->get_date();
-                       ret_val->set_date(&date);
-                       delete(o_data);
-                       delete(n_data);
-               }
-               delete(dr);
-       }
-       return ret_val;
-}
-
-Data *Store::get_mean() {
-       int     row_count;
-       int     col_count;
-       int     ii;
-       Data    *ret_val;
-
-       ret_val = NULL;
-       if (store_data == NULL) {
-               load();
-       }
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               if (row_count > 0) {
-                       col_count       = store_data->get_data_column_count();
-                       ret_val         = get_sum();
-                       if (col_count > 0) {
-                               for (ii = 0; ii < col_count; ii++) {
-                                       ret_val->value_arr[ii]  = ret_val->value_arr[ii] / row_count;
-                                       log_debug("avg: %f\n", ret_val->value_arr[ii]);
-                               }
-                       }
-               }
-       }
-       return ret_val;
-}
-
-Data *Store::get_max() {
-       int     row_count;
-       int     col_count;
-       double  new_val;
-       int     ii;
-       int     jj;
-       Data    *data;
-       Data    *ret_val;
-       double  min_val;
-       Date    date;
-
-       ret_val = NULL;
-       data    = NULL;
-       if (store_data == NULL) {
-               load();
-       }
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               log_debug("data row count: %d\n", row_count);
-               if (row_count > 0) {
-                       col_count       = store_data->get_data_column_count();
-                       log_debug("data item count per row: %d\n", col_count);
-                       min_val         = numeric_limits<double>::min();
-                       data    = store_data->get_data(0);
-                       ret_val         = new Data(col_count,
-                                               min_val,
-                                               data->get_unit());
-                       if (col_count > 0) {
-                               for (ii = 0; ii < row_count - 1; ii++) {
-                                       data    = store_data->get_data(ii);
-                                       for (jj = 0; jj < col_count; jj++) {
-                                               new_val = data->value_arr[jj];
-                                               if (new_val > ret_val->value_arr[jj]) {
-                                                       ret_val->value_arr[jj]  = new_val;
-                                               }
-                                       }
-                                       if (ii < (row_count - 2)) {
-                                               delete(data);
-                                               data    = NULL;
-                                       }
-                               }
-                       }
-                       date    = data->get_date();
-                       ret_val->set_date(&date);
-                       if (data != NULL) {
-                               delete(data);
-                       }
-               }
-       }
-       return ret_val;
-}
-
-Data *Store::get_min() {
-       int     row_count;
-       int     col_count;
-       double  new_val;
-       int     ii;
-       int     jj;
-       Data    *data;
-       Data    *ret_val;
-       double  max_val;
-       Date    date;
-
-       ret_val = NULL;
-       data    = NULL;
-       if (store_data == NULL) {
-               load();
-       }
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               log_debug("data row count: %d\n", row_count);
-               if (row_count > 0) {
-                       col_count       = store_data->get_data_column_count();
-                       log_debug("data item count per row: %d\n", col_count);
-                       max_val         = numeric_limits<double>::max();
-                       data            = store_data->get_data(0);
-                       ret_val         = new Data(col_count,
-                                               max_val,
-                                               data->get_unit());
-                       if (col_count > 0) {
-                               for (ii = 0; ii < row_count - 1; ii++) {
-                                       data    = store_data->get_data(ii);
-                                       for (jj = 0; jj < col_count; jj++) {
-                                               new_val = data->value_arr[jj];
-                                               if (new_val < ret_val->value_arr[jj]) {
-                                                       ret_val->value_arr[jj]  = new_val;
-                                               }
-                                       }
-                                       if (ii < (row_count - 2)) {
-                                               delete(data);
-                                               data    = NULL;
-                                       }
-                               }
-                       }
-                       date    = data->get_date();
-                       ret_val->set_date(&date);
-                       if (data != NULL) {
-                               delete(data);
-                       }
-               }
-       }
-       return ret_val;
-}
-
-vector<Data *> *Store::get_sum(int freq_sec) {
-       int             row_count;
-       int             col_count;
-       int             jj;
-       int             ii;
-       Data            *data;
-       Data            *calc;
-       Date            *limit_d;
-       Date            date;
-       vector<Data *>  *ret_val;
-
-       ret_val = new vector<Data *>();
-       calc    = NULL;
-       limit_d = NULL;
-       if (store_data == NULL) {
-               load();
-       }
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               if (row_count > 0) {
-                       col_count       = store_data->get_data_column_count();
-                       if (col_count > 0) {
-                               for (ii = 0; ii < row_count; ii++) {
-                                       data    = store_data->get_data(ii);
-                                       if (data != NULL) {
-                                               if (calc == NULL) {
-                                                       calc            = data->clone();
-                                                       limit_d         = data->get_date().clone();
-                                                       limit_d->min    = 0;
-                                                       limit_d->sec    = 0;
-                                                       limit_d->inc_seconds(freq_sec);
-                                               }
-                                               else {
-                                                       date    = data->get_date();
-                                                       if (date.before(limit_d)) {
-                                                               for (jj = 0; jj < col_count; jj++) {
-                                                                       calc->value_arr[jj]     = calc->value_arr[jj] + data->value_arr[jj];
-                                                               }
-                                                       }
-                                                       else {
-                                                               ret_val->push_back(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(freq_sec);
-                                                       }
-                                               }
-                                               delete(data);
-                                       }
-                               }
-                               if (calc != NULL) {
-                                       delete(calc);
-                                       calc    = NULL;
-                               }
-                               if (limit_d != NULL) {
-                                       delete(limit_d);
-                               }
-                       }
-               }
-       }
-       return ret_val;
-}
-
-vector<Data *> *Store::get_mean(int freq_sec) {
-       int             row_count;
-       int             col_count;
-       int             d_count;
-       int             jj;
-       int             ii;
-       Data            *data;
-       Data            *calc;
-       Date            *limit_d;
-       Date            date;
-       vector<Data *>  *ret_val;
-
-       ret_val = new vector<Data *>();
-       calc    = NULL;
-       limit_d = NULL;
-       d_count = 1;
-       if (store_data == NULL) {
-               load();
-       }
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               if (row_count > 0) {
-                       col_count       = store_data->get_data_column_count();
-                       if (col_count > 0) {
-                               for (ii = 0; ii < row_count; ii++) {
-                                       data    = store_data->get_data(ii);
-                                       if (data != NULL) {
-                                               if (calc == NULL) {
-                                                       d_count         = 1;
-                                                       calc            = data->clone();
-                                                       limit_d         = data->get_date().clone();
-                                                       limit_d->min    = 0;
-                                                       limit_d->sec    = 0;
-                                                       limit_d->inc_seconds(freq_sec);
-                                               }
-                                               else {
-                                                       date    = data->get_date();
-                                                       if (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++;
-                                                       }
-                                                       else {
-                                                               for (jj = 0; jj < col_count; jj++) {
-                                                                       calc->value_arr[jj]     = calc->value_arr[jj] / d_count;
-                                                               }
-                                                               ret_val->push_back(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(freq_sec);
-                                                       }
-                                               }
-                                               delete(data);
-                                       }
-                               }
-                               if (calc != NULL) {
-                                       delete(calc);
-                                       calc    = NULL;
-                               }
-                               if (limit_d != NULL) {
-                                       delete(limit_d);
-                               }
-                       }
-               }
-       }
-       return ret_val;
-}
-
-vector<Data *> *Store::get_delta(int freq_sec) {
-       int             row_count;
-       int             col_count;
-       int             jj;
-       int             ii;
-       Data            *data;
-       Data            *calc1;
-       Data            *calc2;
-       Date            *limit_d;
-       Date            date;
-       vector<Data *>  *ret_val;
-
-       ret_val = new vector<Data *>();
-       calc1   = NULL;
-       calc2   = NULL;
-       limit_d = NULL;
-       if (store_data == NULL) {
-               load();
-       }
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               if (row_count > 0) {
-                       col_count       = store_data->get_data_column_count();
-                       if (col_count > 0) {
-                               for (ii = 0; ii < row_count; ii++) {
-                                       data    = store_data->get_data(ii);
-                                       if (data != NULL) {
-                                               if (calc1 == NULL) {
-                                                       calc1           = data->clone();
-                                                       limit_d         = data->get_date().clone();
-                                                       limit_d->min    = 0;
-                                                       limit_d->sec    = 0;
-                                                       limit_d->inc_seconds(freq_sec);
-                                                       if (calc2 != NULL) {
-                                                               delete(calc2);
-                                                       }
-                                                       calc2           = NULL;
-                                               }
-                                               else {
-                                                       date    = data->get_date();
-                                                       if (date.before(limit_d)) {
-                                                               if (calc2 != NULL) {
-                                                                       delete(calc2);
-                                                               }
-                                                               calc2   = data->clone();
-                                                       }
-                                                       else {
-                                                               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->push_back(calc2);
-                                                               delete(calc1);
-                                                               calc1   = data->clone();
-                                                               calc2   = NULL; // do not delete calc2 as it's stored to array
-                                                               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(freq_sec);
-                                                       }
-                                               }
-                                               delete(data);
-                                       }
-                               }
-                               if (calc1 != NULL) {
-                                       delete(calc1);
-                                       calc1   = NULL;
-                               }
-                               if (calc2 != NULL) {
-                                       delete(calc2);
-                                       calc2   = NULL;
-                               }
-                               if (limit_d != NULL) {
-                                       delete(limit_d);
-                               }
-                       }
-               }
-       }
-       return ret_val;
-}
-
-vector<Data *> *Store::get_max_or_min(int freq_sec, bool max) {
-       int             row_count;
-       int             col_count;
-       int             jj;
-       int             ii;
-       Data            *data;
-       Data            *calc;
-       Date            *limit_d;
-       Date            date;
-       vector<Data *>  *ret_val;
-
-       ret_val = new vector<Data *>();
-       calc    = NULL;
-       limit_d = NULL;
-       if (store_data == NULL) {
-               load();
-       }
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               if (row_count > 0) {
-                       col_count       = store_data->get_data_column_count();
-                       if (col_count > 0) {
-                               for (ii = 0; ii < row_count; ii++) {
-                                       data    = store_data->get_data(ii);
+       if (access(fname_param.c_str(), R_OK) == 0) {
+               //log_debug("opening file: %s\n", fname_param.c_str());
+               in.open(fname_param.c_str());
+               if (in.is_open() == true) {
+                       while (in.eof() == false) {
+                               getline(in, data_str);
+                               if (data_str.empty() == false) {
+                                       data    = Data::parse_string(data_str);
                                        if (data != NULL) {
-                                               if (calc == NULL) {
-                                                       calc            = data->clone();
-                                                       limit_d         = data->get_date().clone();
-                                                       limit_d->min    = 0;
-                                                       limit_d->sec    = 0;
-                                                       limit_d->inc_seconds(freq_sec);
+                                               if (store_data == NULL) {
+                                                       store_data      = new DataRange(data);
                                                }
                                                else {
-                                                       date    = data->get_date();
-                                                       if (date.before(limit_d)) {
-                                                               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];
-                                                                               }
-                                                                       }
-                                                               }
-                                                               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];
-                                                                               }
-                                                                       }
-                                                               }
-                                                       }
-                                                       else {
-                                                               ret_val->push_back(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(freq_sec);
-                                                       }
+                                                       store_data->add(data);
                                                }
                                                delete(data);
                                        }
                                }
-                               if (calc != NULL) {
-                                       delete(calc);
-                                       calc    = NULL;
-                               }
-                               if (limit_d != NULL) {
-                                       delete(limit_d);
-                               }
-                       }
-               }
-       }
-       return ret_val;
-}
-
-vector<Data *> *Store::get_max(int freq_sec) {
-       vector<Data *>  *ret_val;
-
-       ret_val = get_max_or_min(freq_sec, true);
-       return ret_val;
-}
-
-vector<Data *> *Store::get_min(int freq_sec) {
-       vector<Data *>  *ret_val;
-
-       ret_val = get_max_or_min(freq_sec, false);
-       return ret_val;
-}
-
-DataRange *Store::get_oldest_and_newest_data() {
-       DataRange       *ret_val;
-       ifstream        in;
-       Data            *o_data;
-       Data            *n_data;
-       string          latest;
-       int             row_count;
-       string          line;
-       string          prev_line;
-
-       ret_val = NULL;
-       o_data  = NULL;
-       n_data  = NULL;
-       if (store_data != NULL) {
-               row_count       = store_data->get_data_row_count();
-               if (row_count > 0) {
-                       o_data          = store_data->get_data(0);
-                       n_data          = store_data->get_data(row_count - 1);
-               }
-       }
-       else {
-               if (range_data != NULL) {
-                       row_count       = range_data->get_data_row_count();
-                       if (row_count > 0) {
-                               o_data          = range_data->get_data(0);
-                               n_data          = range_data->get_data(row_count - 1);
                        }
+                       ret_val = true;
                }
                else {
-                       in.open(store_file_name.c_str());
-                       while (in.eof() == false) {
-                               getline(in, line);
-                               if (line.empty() == false) {
-                                       if (o_data == NULL) {
-                                               o_data  = Data::parse_string(line);
-                                       }
-                                       prev_line       = line;
-                               }
-                       }
-                       if (prev_line.empty() == false) {
-                               n_data  = Data::parse_string(prev_line);
-                       }
-               }
-       }
-       if ((o_data != NULL) &&
-           (n_data != NULL)) {
-               ret_val = new DataRange(o_data);
-               ret_val->add_data(n_data);
-               if (range_data != NULL) {
-                       range_data      = new DataRange(o_data);
-                       range_data->add_data(n_data);
+                       log_error("Could not open data file: %s\n", fname_param.c_str());
                }
        }
-       if (o_data != NULL) {
-               delete(o_data);
-       }
-       if (n_data != NULL) {
-               delete(n_data);
-       }
-       return ret_val;
-}
-
-Data *Store::get_oldest_data() {
-       int             row_count;
-       Data            *ret_val;
-       DataRange       *dr;
-
-       ret_val = NULL;
-       dr      = get_oldest_and_newest_data();
-       if (dr != NULL) {
-               row_count       = dr->get_data_row_count();
-               if (row_count >= 1) {
-                       ret_val = dr->get_data(0);
-               }
-               delete(dr);
-       }
-       return ret_val;
-}
-
-Data *Store::get_newest_data() {
-       int             row_count;
-       Data            *ret_val;
-       DataRange       *dr;
-
-       ret_val = NULL;
-       dr      = get_oldest_and_newest_data();
-       if (dr != NULL) {
-               row_count       = dr->get_data_row_count();
-               if (row_count == 2) {
-                       ret_val = dr->get_data(1);
-               }
-               delete(dr);
+       else {
+               log_warning("Could not open data file, file does not exist or user does not have read access for it: %s\n", fname_param.c_str());
        }
        return ret_val;
 }
index 11218f2439f84630f2e73e65e2ce4997e10a00f1..51252ad322d2f6702df8321630f774f64b6c4481 100644 (file)
@@ -1,52 +1,29 @@
 /*
  * Store.hh
  *
- *  Created on: Oct 31, 2010
+ *  Created on: Jan 20, 2011
  *      Author: lamikr
  */
 
-#ifndef W1STORE_HH_
-#define W1STORE_HH_
+#ifndef STORE_HH_
+#define STORE_HH_
 
 #include <string>
-#include <list>
-#include <vector>
-
-#include <stdbool.h>
-
 #include "Data.hh"
 #include "Date.hh"
 
 namespace plp {
        class Store {
                public:
-                       Store(std::string device_id,
-                               plp::Date *date_time);
-                       Store(std::string file_name_param);
+                       Store(std::string device_id, plp::Date *date_time);
                        virtual ~Store();
-                       static std::string get_dir_name(std::string device_id, plp::Date *ltime);
-                       static std::string get_file_name(std::string device_id, plp::Date *ltime);
-                       static void save(std::string device_id, std::list<plp::Data *> *data_list, int dec_precision);
-                       bool load();
-                       plp::Data *get_sum();
-                       plp::Data *get_delta();
-                       plp::Data *get_mean();
-                       plp::Data *get_max();
-                       plp::Data *get_min();
-                       std::vector<plp::Data *> *get_sum(int freq_sec);
-                       std::vector<plp::Data *> *get_mean(int freq_sec);
-                       std::vector<plp::Data *> *get_delta(int freq_sec);
-                       std::vector<plp::Data *> *get_max(int freq_sec);
-                       std::vector<plp::Data *> *get_min(int freq_sec);
-                       plp::Data *get_oldest_data();
-                       plp::Data *get_newest_data();
-                       plp::DataRange *get_oldest_and_newest_data();
                protected:
-                       std::string     store_file_name;
+                       std::string     device_id;
+                       plp::Date       *date;
                        plp::DataRange  *store_data;
                        plp::DataRange  *range_data;
-                       std::vector<plp::Data *> *get_max_or_min(int freq_sec, bool max);
+                       bool load(std::string fname_param);
        };
 }
 
-#endif /* W1STORE_HH_ */
+#endif /* STORE_HH_ */
diff --git a/src/StoreCache.cc b/src/StoreCache.cc
new file mode 100644 (file)
index 0000000..68a9f58
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * StoreCache.cc
+ *
+ *  Created on: Jan 6, 2011
+ *      Author: lamikr
+ */
+#include <plp/log.h>
+
+#include "Store.hh"
+#include "StoreCache.hh"
+#include "StoreDay.hh"
+#include "DeviceConfig.hh"
+#include "W1Util.hh"
+
+using namespace std;
+using namespace plp;
+using namespace w1;
+
+StoreCache::StoreCache(string device_id_param,
+               Date *date_time_param): Store(device_id_param, date_time_param) {
+/*
+       store_fname     = get_file_name(device_id_param,
+                               date_time_param,
+                               period_type_param,
+                               calc_type_param);
+*/
+}
+
+StoreCache::~StoreCache() {
+}
+
+string StoreCache::get_dir_name(string device_id_param,
+                               Date *date_time_param,
+                               EnumSummaryPeriod period_type_param,
+                               EnumSummaryCalculationType calc_type_param) {
+       string  ret_val;
+       char    buffer[30];
+       string  bd_name;
+
+       snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
+       bd_name = DeviceConfig::get_base_dir_name();
+       bd_name = W1Util::concat_paths(bd_name, CACHE_DIR_NAME);
+       bd_name = W1Util::concat_paths(bd_name, device_id_param);
+       bd_name = W1Util::concat_paths(bd_name, SUMMARY_PERIOD_NAMES_ARRAY[period_type_param]);
+       bd_name = W1Util::concat_paths(bd_name, CALCULATION_TYPE_NAMES_ARRAY[calc_type_param]);
+       ret_val = bd_name + "/" + buffer;
+       return ret_val;
+}
+
+string StoreCache::get_file_name(string device_id_param,
+                               Date *date_time_param,
+                               EnumSummaryPeriod period_type_param,
+                               EnumSummaryCalculationType calc_type_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);
+       fname   = buffer;
+       fname   = fname + DATAFILE_SUFFIX;
+       ret_val = get_dir_name(device_id_param, date_time_param, period_type_param, calc_type_param);
+       ret_val = W1Util::concat_paths(ret_val, fname);
+       return ret_val;
+}
+
+DataRange *StoreCache::get_mean(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       StoreDay        *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               MEAN);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               store   = new StoreDay(device_id, date);
+               ret_val = store->get_mean(period_type_param);
+               save(fname, ret_val, 4);
+               delete(store);
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_sum(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       StoreDay        *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               MEAN);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               store   = new StoreDay(device_id, date);
+               ret_val = store->get_sum(period_type_param);
+               save(fname, ret_val, 4);
+               delete(store);
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_delta(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       StoreDay        *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               MEAN);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       // read from cache file
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               store   = new StoreDay(device_id, date);
+               ret_val = store->get_delta(period_type_param);
+               save(fname, ret_val, 4);
+               delete(store);
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_max(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       StoreDay        *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               MEAN);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               store   = new StoreDay(device_id, date);
+               ret_val = store->get_max(period_type_param);
+               save(fname, ret_val, 4);
+               delete(store);
+       }
+       return ret_val;
+}
+
+DataRange *StoreCache::get_min(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       DataRange       *ret_val;
+       Data            *dta;
+       string          fname;
+       StoreDay        *store;
+
+       ret_val = NULL;
+       fname   = get_file_name(device_id,
+                               date,
+                               period_type_param,
+                               MEAN);
+       if (store_data == NULL) {
+               if (access(fname.c_str(), R_OK) == 0) {
+                       load(fname);
+               }
+       }
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       ret_val = new DataRange();
+                       dta     = store_data->get(0);
+                       ret_val->add(dta);
+                       delete(dta);
+               }
+       }
+       if (ret_val == NULL) {
+               store   = new StoreDay(device_id, date);
+               ret_val = store->get_min(period_type_param);
+               save(fname, ret_val, 4);
+               delete(store);
+       }
+       return ret_val;
+}
+
+void StoreCache::save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param) {
+       string          line;
+       Data            *data;
+       ofstream        *ostream;
+       int             ii;
+       int             cnt;
+
+       cnt     = datarange_param->get_count();
+       ostream =  NULL;
+       log_info("[%s] cacheing %d data values.\n", device_id.c_str(), cnt);
+       ostream = W1Util::open_for_writing(fname_param.c_str());
+       if ((ostream != NULL) &&
+           (ostream->is_open() == true)) {
+               // TODO: add mutex to protect string_list while it's read and emptied
+               for(ii = 0; ii < cnt; ii++) {
+                       data    = datarange_param->get(ii);
+                       if (data != NULL) {
+                               line    = data->to_string(decimal_count_param);
+                               if (line.length() > 0) {
+                                       *ostream << line << endl;
+                               }
+                               delete(data);
+                       }
+               }
+       }
+       else {
+               log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), fname_param.c_str());
+       }
+       if (ostream != NULL) {
+               ostream->close();
+               delete(ostream);
+       }
+}
diff --git a/src/StoreCache.hh b/src/StoreCache.hh
new file mode 100644 (file)
index 0000000..dadd6b2
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * StoreCache.hh
+ *
+ *  Created on: Jan 6, 2011
+ *      Author: lamikr
+ */
+
+#ifndef STORECACHE_HH_
+#define STORECACHE_HH_
+
+#include <vector>
+#include <list>
+
+#include "Data.hh"
+#include "Date.hh"
+#include "Store.hh"
+#include "W1Configure.hh"
+
+namespace plp {
+       class StoreCache: public plp::Store {
+               public:
+                       StoreCache(std::string device_id_param,
+                               plp::Date *date_time_param);
+                       virtual ~StoreCache();
+                       plp::DataRange *get_sum(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_mean(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_delta(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_max(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_min(EnumSummaryPeriod period_type_param);
+               protected:
+                       static std::string get_dir_name(std::string device_id_param,
+                                               Date *date_time_param,
+                                               EnumSummaryPeriod period_type_param,
+                                               EnumSummaryCalculationType calc_type_param);
+                       static std::string get_file_name(std::string device_id_param,
+                                               Date *date_time_param,
+                                               EnumSummaryPeriod period_type_param,
+                                               EnumSummaryCalculationType calc_type_param);
+                       void save(std::string fname_param, plp::DataRange *datarange_param, int decimal_count_param);
+       };
+}
+
+#endif /* STORECACHE_HH_ */
diff --git a/src/StoreDay.cc b/src/StoreDay.cc
new file mode 100644 (file)
index 0000000..8d35952
--- /dev/null
@@ -0,0 +1,596 @@
+/*
+ * Store.cc
+ *
+ *  Created on: Oct 31, 2010
+ *      Author: lamikr
+ */
+
+#include <list>
+#include <string>
+#include <fstream>
+#include <limits>
+
+#include <time.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <plp/log.h>
+
+#include "DeviceConfig.hh"
+#include "W1Configure.hh"
+#include "StoreDay.hh"
+#include "W1Util.hh"
+
+using namespace std;
+using namespace w1;
+using namespace plp;
+
+StoreDay::StoreDay(string device_id_param,
+               Date *date_time_param): Store(device_id_param, date_time_param) {
+       store_fname     = get_file_name(device_id_param, date_time_param);
+}
+
+StoreDay::StoreDay(string fname_param): Store("", NULL) {
+       store_data      = NULL;
+       range_data      = NULL;
+       store_fname     = fname_param;
+}
+
+StoreDay::~StoreDay() {
+       if (store_data != NULL) {
+               delete(store_data);
+               store_data      = NULL;
+       }
+}
+
+string StoreDay::get_dir_name(string device_id, Date *date_time_param) {
+       string  ret_val;
+       char    buffer[30];
+       string  bd_name;
+
+       snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
+       bd_name = DeviceConfig::get_base_dir_name();
+       bd_name = W1Util::concat_paths(bd_name, device_id);
+       ret_val = bd_name + "/" + buffer;
+       return ret_val;
+}
+
+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);
+       fname   = buffer;
+       fname   = fname + DATAFILE_SUFFIX;
+       ret_val = get_dir_name(device_id, date_time_param);
+       ret_val = W1Util::concat_paths(ret_val, fname);
+       return ret_val;
+}
+
+void StoreDay::save(string device_id,
+               std::list<Data *> *data_list,
+               int dec_precision) {
+       string                  n_path;
+       string                  f_path;
+       string                  line;
+       Data                    *data;
+       ofstream                *ostream;
+       Date                    date;
+       list<Data *>::iterator  iter;
+
+       ostream =  NULL;
+       f_path  = "";
+       log_info("[%s] writing %d data values to save.\n", device_id.c_str(), data_list->size());
+       // TODO: add mutex to protect string_list while it's read and emptied
+       for(iter = data_list->begin(); iter != data_list->end(); iter++) {
+               data    = (Data *)*iter;
+               date    = data->get_date();
+               n_path  = get_file_name(device_id, &date);
+               if (n_path.compare(f_path) != 0) {
+                       if (ostream != NULL) {
+                               ostream->close();
+                               delete(ostream);
+                       }
+                       f_path  = n_path;
+                       log_info("[%s] Opening file for save: %s\n", device_id.c_str(), f_path.c_str());
+                       ostream = W1Util::open_for_writing(f_path.c_str());
+               }
+               if ((ostream != NULL) &&
+                   (ostream->is_open() == true)) {
+                       line    = data->to_string(dec_precision);
+                       if (line.length() > 0) {
+                               log_debug("storing line: %s\n", line.c_str());
+                               *ostream << line << endl;
+                       }
+               }
+               else {
+                       log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), f_path.c_str());
+               }
+       }
+       if (ostream != NULL) {
+               ostream->close();
+               delete(ostream);
+       }
+}
+
+bool StoreDay::load() {
+       return Store::load(store_fname);
+}
+
+bool StoreDay::exist(string fname_param) {
+       bool    ret_val;
+       ret_val = (access(fname_param.c_str(), F_OK) == 0);
+       return ret_val;
+}
+
+bool StoreDay::exist() {
+       return exist(store_fname);
+}
+
+static int get_summary_period_as_freq_seconds(EnumSummaryPeriod period_type_param) {
+       int     ret_val;
+
+       ret_val = 3600;
+       switch(period_type_param) {
+               case PERIOD_SECONDLY:
+                       ret_val = 1;
+                       break;
+               case PERIOD_MINUTELY:
+                       ret_val = 60;
+                       break;
+               case PERIOD_HOURLY:
+                       ret_val = 3600;
+                       break;
+               case PERIOD_DAILY:
+               case PERIOD_MONTHLY:
+               case PERIOD_YEARLY:
+               default:
+                       // -1 as freq means that show all data from the current store
+                       ret_val = -1;
+                       break;
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_sum(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       int             col_count;
+       int             jj;
+       int             ii;
+       Data            *data;
+       Data            *calc;
+       Date            *limit_d;
+       Date            date;
+       DataRange       *ret_val;
+       int             frq_sec;
+
+       ret_val = new DataRange();
+       calc    = NULL;
+       limit_d = NULL;
+       frq_sec = get_summary_period_as_freq_seconds(period_type_param);
+       if (store_data == NULL) {
+               load();
+       }
+       if (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) {
+                               for (ii = 0; ii < row_count; ii++) {
+                                       data    = store_data->get(ii);
+                                       if (data != NULL) {
+                                               if (calc == NULL) {
+                                                       calc            = data->clone();
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       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];
+                                                               }
+                                                       }
+                                                       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);
+                                       }
+                               }
+                               if (calc != NULL) {
+                                       delete(calc);
+                                       calc    = NULL;
+                               }
+                               if (limit_d != NULL) {
+                                       delete(limit_d);
+                               }
+                       }
+               }
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_mean(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       int             col_count;
+       int             d_count;
+       int             jj;
+       int             ii;
+       Data            *data;
+       Data            *calc;
+       Date            *limit_d;
+       Date            date;
+       DataRange       *ret_val;
+       int             frq_sec;
+
+       ret_val = new DataRange();
+       calc    = NULL;
+       limit_d = NULL;
+       d_count = 1;
+       frq_sec = get_summary_period_as_freq_seconds(period_type_param);
+       if (store_data == NULL) {
+               load();
+       }
+       if (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) {
+                               for (ii = 0; ii < row_count; ii++) {
+                                       data    = store_data->get(ii);
+                                       if (data != NULL) {
+                                               if (calc == NULL) {
+                                                       d_count         = 1;
+                                                       calc            = data->clone();
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       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++;
+                                                       }
+                                                       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);
+                                       }
+                               }
+                               if (calc != NULL) {
+                                       delete(calc);
+                                       calc    = NULL;
+                               }
+                               if (limit_d != NULL) {
+                                       delete(limit_d);
+                               }
+                       }
+               }
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_delta(EnumSummaryPeriod period_type_param) {
+       int             row_count;
+       int             col_count;
+       int             jj;
+       int             ii;
+       Data            *data;
+       Data            *calc1;
+       Data            *calc2;
+       Date            *limit_d;
+       Date            date;
+       DataRange       *ret_val;
+       int             frq_sec;
+
+       ret_val = new DataRange();
+       calc1   = NULL;
+       calc2   = NULL;
+       limit_d = NULL;
+       frq_sec = get_summary_period_as_freq_seconds(period_type_param);
+       if (store_data == NULL) {
+               load();
+       }
+       if (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) {
+                               for (ii = 0; ii < row_count; ii++) {
+                                       data    = store_data->get(ii);
+                                       if (data != NULL) {
+                                               if (calc1 == NULL) {
+                                                       calc1           = data->clone();
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       limit_d->sec    = 0;
+                                                       limit_d->inc_seconds(frq_sec);
+                                                       if (calc2 != NULL) {
+                                                               delete(calc2);
+                                                       }
+                                                       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();
+                                                               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);
+                                       }
+                               }
+                               if (calc1 != NULL) {
+                                       delete(calc1);
+                                       calc1   = NULL;
+                               }
+                               if (calc2 != NULL) {
+                                       delete(calc2);
+                                       calc2   = NULL;
+                               }
+                               if (limit_d != NULL) {
+                                       delete(limit_d);
+                               }
+                       }
+               }
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_max_or_min(EnumSummaryPeriod period_type_param, bool max) {
+       int             row_count;
+       int             col_count;
+       int             jj;
+       int             ii;
+       Data            *data;
+       Data            *calc;
+       Date            *limit_d;
+       Date            date;
+       DataRange       *ret_val;
+       int             frq_sec;
+
+       ret_val = new DataRange();
+       calc    = NULL;
+       limit_d = NULL;
+       frq_sec = get_summary_period_as_freq_seconds(period_type_param);
+       if (store_data == NULL) {
+               load();
+       }
+       if (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) {
+                               for (ii = 0; ii < row_count; ii++) {
+                                       data    = store_data->get(ii);
+                                       if (data != NULL) {
+                                               if (calc == NULL) {
+                                                       calc            = data->clone();
+                                                       limit_d         = data->get_date().clone();
+                                                       limit_d->min    = 0;
+                                                       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)))) {
+                                                               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];
+                                                                               }
+                                                                       }
+                                                               }
+                                                               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];
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                                       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);
+                                       }
+                               }
+                               if (calc != NULL) {
+                                       delete(calc);
+                                       calc    = NULL;
+                               }
+                               if (limit_d != NULL) {
+                                       delete(limit_d);
+                               }
+                       }
+               }
+       }
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_max(EnumSummaryPeriod period_type_param) {
+       DataRange       *ret_val;
+
+       ret_val = get_max_or_min(period_type_param, true);
+       return ret_val;
+}
+
+plp::DataRange *StoreDay::get_min(EnumSummaryPeriod period_type_param) {
+       DataRange       *ret_val;
+
+       ret_val = get_max_or_min(period_type_param, false);
+       return ret_val;
+}
+
+DataRange *StoreDay::get_oldest_and_newest_data(string fname_param) {
+       DataRange       *ret_val;
+       ifstream        in;
+       Data            *o_data;
+       Data            *n_data;
+       string          latest;
+       int             row_count;
+       string          line;
+       string          prev_line;
+
+       ret_val = NULL;
+       o_data  = NULL;
+       n_data  = NULL;
+       if (store_data != NULL) {
+               row_count       = store_data->get_count();
+               if (row_count > 0) {
+                       o_data          = store_data->get(0);
+                       n_data          = store_data->get(row_count - 1);
+               }
+       }
+       else {
+               if (range_data != NULL) {
+                       row_count       = range_data->get_count();
+                       if (row_count > 0) {
+                               o_data          = range_data->get(0);
+                               n_data          = range_data->get(row_count - 1);
+                       }
+               }
+               else {
+                       in.open(fname_param.c_str());
+                       while (in.eof() == false) {
+                               getline(in, line);
+                               if (line.empty() == false) {
+                                       if (o_data == NULL) {
+                                               o_data  = Data::parse_string(line);
+                                       }
+                                       prev_line       = line;
+                               }
+                       }
+                       if (prev_line.empty() == false) {
+                               n_data  = Data::parse_string(prev_line);
+                       }
+               }
+       }
+       if ((o_data != NULL) &&
+           (n_data != NULL)) {
+               ret_val = new DataRange(o_data);
+               ret_val->add(n_data);
+               if (range_data != NULL) {
+                       range_data      = new DataRange(o_data);
+                       range_data->add(n_data);
+               }
+       }
+       if (o_data != NULL) {
+               delete(o_data);
+       }
+       if (n_data != NULL) {
+               delete(n_data);
+       }
+       return ret_val;
+}
+
+DataRange *StoreDay::get_oldest_and_newest_data() {
+       return get_oldest_and_newest_data(store_fname);
+}
+
+Data *StoreDay::get_oldest_data() {
+       int             row_count;
+       Data            *ret_val;
+       DataRange       *dr;
+
+       ret_val = NULL;
+       dr      = get_oldest_and_newest_data();
+       if (dr != NULL) {
+               row_count       = dr->get_count();
+               if (row_count >= 1) {
+                       ret_val = dr->get(0);
+               }
+               delete(dr);
+       }
+       return ret_val;
+}
+
+Data *StoreDay::get_newest_data() {
+       int             row_count;
+       Data            *ret_val;
+       DataRange       *dr;
+
+       ret_val = NULL;
+       dr      = get_oldest_and_newest_data();
+       if (dr != NULL) {
+               row_count       = dr->get_count();
+               if (row_count == 2) {
+                       ret_val = dr->get(1);
+               }
+               delete(dr);
+       }
+       return ret_val;
+}
diff --git a/src/StoreDay.hh b/src/StoreDay.hh
new file mode 100644 (file)
index 0000000..805777d
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Store.hh
+ *
+ *  Created on: Oct 31, 2010
+ *      Author: lamikr
+ */
+
+#ifndef W1STORE_HH_
+#define W1STORE_HH_
+
+#include <string>
+#include <list>
+#include <vector>
+
+#include <stdbool.h>
+
+#include "Data.hh"
+#include "Date.hh"
+#include "Store.hh"
+
+namespace plp {
+       class StoreDay: public plp::Store {
+               public:
+                       StoreDay(std::string device_id_param,
+                               plp::Date *date_time_param);
+                       StoreDay(std::string file_name_param);
+                       virtual ~StoreDay();
+                       static void save(std::string device_id, std::list<plp::Data *> *data_list, int dec_precision);
+                       plp::DataRange *get_sum(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_mean(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_delta(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_max(EnumSummaryPeriod period_type_param);
+                       plp::DataRange *get_min(EnumSummaryPeriod period_type_param);
+                       plp::Data *get_oldest_data();
+                       plp::Data *get_newest_data();
+                       plp::DataRange *get_oldest_and_newest_data();
+                       /*
+                        * Checks whether store file exist.
+                        */
+                       bool exist();
+               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_file_name(std::string device_id,
+                                                       plp::Date *date_time_param);
+                       plp::DataRange *get_oldest_and_newest_data(std::string fname_param);
+                       bool exist(std::string fname_param);
+       };
+}
+
+#endif /* W1STORE_HH_ */
index 0d02eb21e2f1354f41f1ac6bb2e1e8dcd5eac58c..9886193a235f57b4366247022d3d7adc1a2dfa37 100644 (file)
@@ -8,7 +8,14 @@
 #ifndef W1CONFIGURE_HH_
 #define W1CONFIGURE_HH_
 
+enum EnumSummaryPeriod{PERIOD_YEARLY, PERIOD_MONTHLY, PERIOD_DAILY, PERIOD_HOURLY, PERIOD_MINUTELY, PERIOD_SECONDLY};
+const std::string SUMMARY_PERIOD_NAMES_ARRAY[] = {"yearly", "monthly", "daily", "minutely", "secondly"};
+
+enum EnumSummaryCalculationType {SUM, DELTA, MIN, MAX, MEAN};
+const std::string CALCULATION_TYPE_NAMES_ARRAY[]       = {"sum", "delta", "min", "max", "mean"};
+
 #define DEFAULT_STORAGE_BASE_DIR       "/tmp"
 #define DATAFILE_SUFFIX                        ".txt"
+#define CACHE_DIR_NAME                 "cache"
 
 #endif /* W1CONFIGURE_HH_ */
index 429a5e822baacb581aa17bcf9bf5c3b10ee4aee5..17164eabba9c68cc08341dbdd5e16284055d099e 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "DeviceConfig.hh"
 #include "Factory.hh"
-#include "Store.hh"
+#include "StoreDay.hh"
 #include "W1Device.hh"
 
 using namespace std;
@@ -130,7 +130,7 @@ void W1Device::save_data() {
        int                     dec_precision;
 
        dec_precision   = get_data_decimal_precision();
-       Store::save(id, &memory_cache, dec_precision);
+       StoreDay::save(id, &memory_cache, dec_precision);
        for(iter = memory_cache.begin(); iter != memory_cache.end(); iter++) {
                data    = (Data *)*iter;
                delete(data);
index 1ba7005ab3584c96b81b68c7b533de09954fb71c..b9b8b7adbfde55100718137f39dc84e4e8c04dff 100644 (file)
@@ -71,10 +71,10 @@ int main(int argc, char** argv) {
                if (dta != NULL) {
                        dr      = dta->get_data_range();
                        if (dr != NULL) {
-                               fdata   = dr->get_first_data();
+                               fdata   = dr->get_first();
                                if (fdata != NULL) {
                                        fdata->printout();
-                                       ldata   = dr->get_last_data();
+                                       ldata   = dr->get_last();
                                        if (ldata != NULL) {
                                                ldata->printout();
                                                plp::Date d1;
index cbba3d3adfeb74171d0daf00b3a10886edc66fd1..141031b50c35fe58134937c9085a633e77da3eb6 100644 (file)
@@ -87,6 +87,7 @@ int main(int argc, char** argv) {
                        sleep(scan_interval);
                        if (round >= store_interval) {
                                round = 0;
+                               break;
                        }
                }
        }