From 8de2253c28d95907436b2e26f0805dd83e85a8ce Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Fri, 19 Apr 2013 21:54:11 +0200 Subject: leveldb: /api/value mit server geniertem timestamp --- datastore-leveldb/bin/insert_testdata.py | 13 ++++++---- datastore-leveldb/src/db.cpp | 20 +++++++++++++-- datastore-leveldb/src/db.h | 5 ++++ datastore-leveldb/src/server.cpp | 3 +++ datastore-leveldb/src/web.cpp | 44 +++++++++++++++++++------------- datastore-leveldb/src/web.h | 3 +++ datastore-leveldb/wwwroot/src/ebus.js | 2 +- 7 files changed, 64 insertions(+), 26 deletions(-) diff --git a/datastore-leveldb/bin/insert_testdata.py b/datastore-leveldb/bin/insert_testdata.py index 6ea1180..5f396a9 100644 --- a/datastore-leveldb/bin/insert_testdata.py +++ b/datastore-leveldb/bin/insert_testdata.py @@ -7,17 +7,20 @@ s = ["heizkreisregler9.solarDaten.tempKollektor", "heizkreisregler10.betriebsdatenRegler1.kesselTemperatur", "feuerungsautomat1.betriebsdatenRegler1.aussenTemperatur"] -MINUTE = 1000 * 60 -DAY = MINUTE * 60 * 24 +MILLISEC = 1 +SECOND = 1000 * MILLISEC +MINUTE = SECOND * 60 +HOUR = MINUTE * 60 +DAY = HOUR * 24 NOW = long(time.time()*1000) -FROM=NOW-DAY*30 +FROM=NOW-5*HOUR TO=NOW -STEP=MINUTE +STEP=500 * MILLISEC for i in range(FROM,TO,STEP): for j,sensor in zip(range(len(s)),s): - x = (float(i)/DAY)+j + x = (float(i)/MINUTE)+j requests.put("http://localhost:8080/api/value/"+sensor+"/"+str(i), str(50+50*math.sin(x))) diff --git a/datastore-leveldb/src/db.cpp b/datastore-leveldb/src/db.cpp index 84e30f3..58889dd 100644 --- a/datastore-leveldb/src/db.cpp +++ b/datastore-leveldb/src/db.cpp @@ -1,9 +1,10 @@ #include "db.h" +#include #include #include -#include #include +#include static std::unordered_map dbs; static std::mutex getDBmutex; @@ -20,6 +21,13 @@ static bool sensor_name_is_sane(std::string& name) { return true; } +std::string make_key(const uint64_t timestamp) { + std::stringstream key; + key << "ts-"; + key << std::setfill('0') << std::setw(20) << timestamp; + return key.str(); +} + leveldb::DB *getDB(std::string& name) { getDBmutex.lock(); if (dbs.find(name) == dbs.end()) { @@ -30,7 +38,7 @@ leveldb::DB *getDB(std::string& name) { leveldb::DB *db; leveldb::Options options; options.create_if_missing = true; - leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb."+name, &db); + leveldb::Status status = leveldb::DB::Open(options, "data/"+name, &db); if (not status.ok()) { std::cout << status.ToString() << std::endl; getDBmutex.unlock(); @@ -46,6 +54,14 @@ leveldb::DB *getDB(std::string& name) { } +bool db_insert(std::string& name, const uint64_t timestamp, std::string& value) { + leveldb::DB *db = getDB(name); + if (db == nullptr) return false; + + auto status = db->Put(leveldb::WriteOptions(), make_key(timestamp), value); + return status.ok(); +} + void closeDB() { std::cout << "Close Databases: "; auto it = dbs.begin(); diff --git a/datastore-leveldb/src/db.h b/datastore-leveldb/src/db.h index c7ed25b..9c4c9fb 100644 --- a/datastore-leveldb/src/db.h +++ b/datastore-leveldb/src/db.h @@ -5,6 +5,11 @@ leveldb::DB *getDB(std::string& name); +bool db_insert(std::string& name, const uint64_t timestamp, std::string& value); + void closeDB(); + +std::string make_key(const uint64_t timestamp); + #endif /*HAVE_DB_H*/ diff --git a/datastore-leveldb/src/server.cpp b/datastore-leveldb/src/server.cpp index 3000a25..4776f33 100644 --- a/datastore-leveldb/src/server.cpp +++ b/datastore-leveldb/src/server.cpp @@ -56,6 +56,9 @@ int main(int argc, char **argv) { web_handler.push_front(std::make_pair( web_handle_api_value_R, web_handle_api_value)); + web_handler.push_front(std::make_pair( + web_handle_api_value_timestamp_R, + web_handle_api_value_timestamp)); web_handler.push_front(std::make_pair( web_handle_api_range_R, web_handle_api_range)); diff --git a/datastore-leveldb/src/web.cpp b/datastore-leveldb/src/web.cpp index efff6b9..125a4ad 100644 --- a/datastore-leveldb/src/web.cpp +++ b/datastore-leveldb/src/web.cpp @@ -1,17 +1,14 @@ #include "web.h" #include "db.h" #include -#include +#include #include -#include static const leveldb::Comparator *cmp = leveldb::BytewiseComparator(); -static inline std::string make_key(uint64_t timestamp) { - std::stringstream key; - key << "ts-"; - key << std::setfill('0') << std::setw(20) << timestamp; - return key.str(); +static inline uint64_t now() { + return std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()).count(); } static inline bool parse_key(leveldb::Slice &&key, uint64_t *value) { @@ -21,25 +18,36 @@ static inline bool parse_key(leveldb::Slice &&key, uint64_t *value) { return true; } - const boost::regex web_handle_api_value_R( - "/api/value/([a-zA-Z0-9\\.]+)/([0-9]+)"); + "/api/value/([a-zA-Z0-9\\.]+)"); void web_handle_api_value(const boost::cmatch &match, struct mg_connection *conn) { std::string sensor(match[1].str()); - uint64_t timestamp = std::stoul(match[2].str()); + uint64_t timestamp = now(); char buf[1024]; - int count = mg_read(conn, buf, 1024); - std::string value(buf, count); + int bytesRead = mg_read(conn, buf, 1024); + std::string value(buf, bytesRead); - leveldb::DB *db = getDB(sensor); - if (db == nullptr) { - std::cout << "failed to get db for " << sensor << std::endl; + if (db_insert(sensor, timestamp, value)) { + mg_printf(conn, "HTTP/1.1 200 OK Value received\r\n\r\n"); + } else { mg_printf(conn, "HTTP/1.1 500 Internal Error\r\n\r\n"); - return; } +} - db->Put(leveldb::WriteOptions(), make_key(timestamp), value); - mg_printf(conn, "HTTP/1.1 200 Value received\r\n\r\n"); +const boost::regex web_handle_api_value_timestamp_R( + "/api/value/([a-zA-Z0-9\\.]+)/([0-9]+)"); +void web_handle_api_value_timestamp(const boost::cmatch &match, struct mg_connection *conn) { + std::string sensor(match[1].str()); + uint64_t timestamp = std::stoul(match[2].str()); + char buf[1024]; + int bytesRead = mg_read(conn, buf, 1024); + std::string value(buf, bytesRead); + + if (db_insert(sensor, timestamp, value)) { + mg_printf(conn, "HTTP/1.1 200 OK Value received\r\n\r\n"); + } else { + mg_printf(conn, "HTTP/1.1 500 Internal Error\r\n\r\n"); + } } static inline void print_json_tuple(struct mg_connection *conn, diff --git a/datastore-leveldb/src/web.h b/datastore-leveldb/src/web.h index acb38f5..a9d4593 100644 --- a/datastore-leveldb/src/web.h +++ b/datastore-leveldb/src/web.h @@ -9,6 +9,9 @@ extern "C" { extern const boost::regex web_handle_api_value_R; void web_handle_api_value(const boost::cmatch &match, struct mg_connection *conn); +extern const boost::regex web_handle_api_value_timestamp_R; +void web_handle_api_value_timestamp(const boost::cmatch &match, struct mg_connection *conn); + extern const boost::regex web_handle_api_range_R; void web_handle_api_range(const boost::cmatch &match, struct mg_connection *conn); diff --git a/datastore-leveldb/wwwroot/src/ebus.js b/datastore-leveldb/wwwroot/src/ebus.js index ce4b876..c90cb31 100644 --- a/datastore-leveldb/wwwroot/src/ebus.js +++ b/datastore-leveldb/wwwroot/src/ebus.js @@ -15,7 +15,7 @@ var timeToLocal = function(d) { return d - new Date().getTimezoneOffset() * 60 * $(document).ready(function(){ var from = d.now - 1*d.day; var to = d.now; - var fromOverview = d.now - 30*d.day; + var fromOverview = d.now - 24 * d.hour; var toOverview = d.now; var datasetDetail = [] var datasetOverview = []; -- cgit v1.2.1