diff --git a/include/HostTimeseriesPoint.h b/include/HostTimeseriesPoint.h new file mode 100644 index 0000000000..5a7a13074a --- /dev/null +++ b/include/HostTimeseriesPoint.h @@ -0,0 +1,13 @@ +class HostTimeseriesPoint: public TimeseriesPoint { + public: + nDPIStats *ndpi; + u_int64_t sent, rcvd; + u_int32_t num_flows_as_client, num_flows_as_server; + TrafficCounter l4_stats[4]; // tcp, udp, icmp, other + u_int32_t num_contacts_as_cli, num_contacts_as_srv; + + HostTimeseriesPoint(); + virtual ~HostTimeseriesPoint(); + virtual void lua(lua_State* vm, NetworkInterface *iface); +}; + diff --git a/include/LocalHost.h b/include/LocalHost.h index 93da2daf76..414255910e 100644 --- a/include/LocalHost.h +++ b/include/LocalHost.h @@ -24,8 +24,6 @@ #include "ntop_includes.h" -class HostTimeseriesPoint; - class LocalHost : public Host { private: int16_t local_network_id; @@ -46,7 +44,7 @@ class LocalHost : public Host { u_int32_t attacker_max_num_syn_per_sec, victim_max_num_syn_per_sec; AlertCounter *syn_flood_attacker_alert, *syn_flood_victim_alert; AlertCounter *flow_flood_attacker_alert, *flow_flood_victim_alert; - TimeSeriesRing *ts_ring; + TimeseriesRing *ts_ring; map contacts_as_cli, contacts_as_srv; void initialize(); @@ -102,17 +100,4 @@ class LocalHost : public Host { void makeTsPoint(HostTimeseriesPoint *pt); }; -class HostTimeseriesPoint: public TimeseriesPoint { - public: - nDPIStats *ndpi; - u_int64_t sent, rcvd; - u_int32_t num_flows_as_client, num_flows_as_server; - TrafficCounter l4_stats[4]; // tcp, udp, icmp, other - u_int32_t num_contacts_as_cli, num_contacts_as_srv; - - HostTimeseriesPoint(); - virtual ~HostTimeseriesPoint(); - virtual void lua(lua_State* vm, NetworkInterface *iface); -}; - #endif /* _LOCAL_HOST_H_ */ diff --git a/include/NetworkInterface.h b/include/NetworkInterface.h index f7257bfddc..0ea92d0682 100644 --- a/include/NetworkInterface.h +++ b/include/NetworkInterface.h @@ -124,8 +124,8 @@ class NetworkInterface : public Checkpointable { FlowHash *flows_hash; /**< Hash used to store flows information. */ u_int32_t last_remote_pps, last_remote_bps; u_int8_t packet_drops_alert_perc; - TimeSeriesExporter *tsExporter; - TimeSeriesRing *ts_ring; + TimeseriesExporter *tsExporter; + TimeseriesRing *ts_ring; /* Sub-interface views */ u_int8_t numSubInterfaces; @@ -686,7 +686,7 @@ class NetworkInterface : public Checkpointable { #ifdef HAVE_NINDEX NIndexFlowDB* getNindex(); #endif - inline TimeSeriesExporter* getTSExporter() { if(!tsExporter) tsExporter = new TimeSeriesExporter(this); return(tsExporter); } + inline TimeseriesExporter* getTSExporter() { if(!tsExporter) tsExporter = new TimeseriesExporter(this); return(tsExporter); } inline uint32_t getMaxSpeed() { return(ifSpeed); } virtual void sendTermination() { ; } virtual bool read_from_pcap_dump() { return(false); }; diff --git a/include/TimeSeriesExporter.h b/include/TimeseriesExporter.h similarity index 92% rename from include/TimeSeriesExporter.h rename to include/TimeseriesExporter.h index 49b645e3b4..129d4952bb 100644 --- a/include/TimeSeriesExporter.h +++ b/include/TimeseriesExporter.h @@ -24,7 +24,7 @@ #include "ntop_includes.h" -class TimeSeriesExporter { +class TimeseriesExporter { private: time_t flushTime; u_int32_t cursize; @@ -39,8 +39,8 @@ class TimeSeriesExporter { void createDump(); public: - TimeSeriesExporter(NetworkInterface *_if); - ~TimeSeriesExporter(); + TimeseriesExporter(NetworkInterface *_if); + ~TimeseriesExporter(); void exportData(char *data, bool do_lock = true); void flush(); diff --git a/include/TimeseriesPoint.h b/include/TimeseriesPoint.h new file mode 100644 index 0000000000..3f684fe37e --- /dev/null +++ b/include/TimeseriesPoint.h @@ -0,0 +1,36 @@ +/* + * + * (C) 2018 - ntop.org + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _TIMESERIES_POINT_H_ +#define _TIMESERIES_POINT_H_ + +#include "ntop_includes.h" + +class TimeseriesPoint { + public: + time_t timestamp; + + virtual ~TimeseriesPoint() {}; + virtual void lua(lua_State* vm, NetworkInterface *iface) = 0; +}; + +#endif /* _TIMESERIES_POINT_H_ */ + diff --git a/include/TimeSeriesRing.h b/include/TimeseriesRing.h similarity index 75% rename from include/TimeSeriesRing.h rename to include/TimeseriesRing.h index f6df1cf75a..6bba93098a 100644 --- a/include/TimeSeriesRing.h +++ b/include/TimeseriesRing.h @@ -19,29 +19,19 @@ * */ -#ifndef _TS_AGGREGATOR_H_ -#define _TS_AGGREGATOR_H_ +#ifndef _TIMESERIES_RING_H_ +#define _TIMESERIES_RING_H_ #include "ntop_includes.h" -class TsRingStatus; - -class TimeseriesPoint { - public: - time_t timestamp; - - virtual ~TimeseriesPoint() {}; - virtual void lua(lua_State* vm, NetworkInterface *iface) = 0; -}; - -class TimeSeriesRing { +class TimeseriesRing { protected: NetworkInterface *iface; - TsRingStatus *status, *status_shadow; + TimeseriesRingStatus *status, *status_shadow; public: - TimeSeriesRing(NetworkInterface *iface); - ~TimeSeriesRing(); + TimeseriesRing(NetworkInterface *iface); + ~TimeseriesRing(); bool isTimeToInsert(); void insert(TimeseriesPoint *pt, time_t when); void lua(lua_State* vm); @@ -50,4 +40,4 @@ class TimeSeriesRing { static void luaSinglePoint(lua_State* vm, NetworkInterface *iface, TimeseriesPoint *pt); }; -#endif +#endif /* _TIMESERIES_RING_H_ */ diff --git a/include/TimeseriesRingStatus.h b/include/TimeseriesRingStatus.h new file mode 100644 index 0000000000..a31a4ce99c --- /dev/null +++ b/include/TimeseriesRingStatus.h @@ -0,0 +1,42 @@ +/* + * + * (C) 2018 - ntop.org + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _TIMESERIES_RING_STATUS_H_ +#define _TIMESERIES_RING_STATUS_H_ + +#include "ntop_includes.h" + + +class TimeseriesRingStatus { + public: + TimeseriesPoint **ts_points; + u_int8_t max_points, available_points, point_idx; + u_int8_t num_steps, cur_steps; + + TimeseriesRingStatus(u_int8_t, u_int8_t); + ~TimeseriesRingStatus(); + + void insert(TimeseriesPoint *pt, time_t when); + void lua(lua_State* vm, NetworkInterface *iface); + inline bool isTimeToInsert() { return(++cur_steps >= num_steps); } +}; + +#endif /* _TIMESERIES_RING_STATUS_H_ */ diff --git a/include/ntop_includes.h b/include/ntop_includes.h index f20abf846d..67d0aec522 100644 --- a/include/ntop_includes.h +++ b/include/ntop_includes.h @@ -215,6 +215,7 @@ using namespace std; #include "ProtoStats.h" #include "TcpPacketStats.h" #include "EthStats.h" + #include "LocalTrafficStats.h" #include "PacketDumperGeneric.h" #include "PacketDumper.h" @@ -232,8 +233,13 @@ using namespace std; #if defined(NTOPNG_PRO) && defined(HAVE_NINDEX) #include "nindex_api.h" #endif -#include "TimeSeriesExporter.h" -#include "TimeSeriesRing.h" + +#include "TimeseriesPoint.h" +#include "TimeseriesRingStatus.h" +#include "TimeseriesRing.h" +#include "TimeseriesExporter.h" +#include "TimeseriesRing.h" +#include "HostTimeseriesPoint.h" #include "NetworkInterface.h" #ifndef HAVE_NEDGE #include "PcapInterface.h" diff --git a/src/Flow.cpp b/src/Flow.cpp index 314e8d875b..20a1d4d33b 100644 --- a/src/Flow.cpp +++ b/src/Flow.cpp @@ -2656,7 +2656,7 @@ void Flow::dissectHTTP(bool src2dst_direction, char *payload, u_int16_t payload_ dissect_next_http_packet = true; /* use memchr to prevent possibly non-NULL terminated HTTP requests */ - if(payload && ((space = (char*)memchr(payload, ' ', payload_len)) != NULL)) { + if(payload && ((space = (char*)memchr(payload, ' ', payload_len-1)) != NULL)) { u_int l = space - payload; if((!strncmp(payload, "GET", 3)) diff --git a/src/LocalHost.cpp b/src/LocalHost.cpp index f3b4c47734..384f9ac73a 100644 --- a/src/LocalHost.cpp +++ b/src/LocalHost.cpp @@ -139,8 +139,8 @@ void LocalHost::initialize() { ts_ring = NULL; - if(TimeSeriesRing::isRingEnabled(ntop->getPrefs())) - ts_ring = new TimeSeriesRing(iface); + if(TimeseriesRing::isRingEnabled(ntop->getPrefs())) + ts_ring = new TimeseriesRing(iface); } /* *************************************** */ @@ -739,13 +739,13 @@ void LocalHost::updateStats(struct timeval *tv) { nextSitesUpdate = tv->tv_sec + HOST_SITES_REFRESH; } - if(!ts_ring && TimeSeriesRing::isRingEnabled(ntop->getPrefs())) - ts_ring = new TimeSeriesRing(iface); + if(!ts_ring && TimeseriesRing::isRingEnabled(ntop->getPrefs())) + ts_ring = new TimeseriesRing(iface); if(ts_ring && ts_ring->isTimeToInsert()) { HostTimeseriesPoint *pt = new HostTimeseriesPoint(); - makeTsPoint(pt); + makeTsPoint(pt); /* Ownership of the point is passed to the ring */ ts_ring->insert(pt, last_update_time.tv_sec); } @@ -795,11 +795,12 @@ void LocalHost::setOS(char *_os) { /* *************************************** */ void LocalHost::tsLua(lua_State* vm) { - if(!ts_ring || !TimeSeriesRing::isRingEnabled(ntop->getPrefs())) { + if(!ts_ring || !TimeseriesRing::isRingEnabled(ntop->getPrefs())) { /* Use real time data */ HostTimeseriesPoint pt; + makeTsPoint(&pt); - TimeSeriesRing::luaSinglePoint(vm, iface, &pt); + TimeseriesRing::luaSinglePoint(vm, iface, &pt); } else ts_ring->lua(vm); } diff --git a/src/NetworkInterface.cpp b/src/NetworkInterface.cpp index 8790ca7e90..2482ee9f58 100644 --- a/src/NetworkInterface.cpp +++ b/src/NetworkInterface.cpp @@ -333,8 +333,8 @@ void NetworkInterface::init() { ts_ring = NULL; - if(TimeSeriesRing::isRingEnabled(ntop->getPrefs())) - ts_ring = new TimeSeriesRing(this); + if(TimeseriesRing::isRingEnabled(ntop->getPrefs())) + ts_ring = new TimeseriesRing(this); } /* **************************************************** */ @@ -2858,8 +2858,8 @@ void NetworkInterface::periodicStatsUpdate() { host_pools->updateStats(&tv); #endif - if(!ts_ring && TimeSeriesRing::isRingEnabled(ntop->getPrefs())) - ts_ring = new TimeSeriesRing(this); + if(!ts_ring && TimeseriesRing::isRingEnabled(ntop->getPrefs())) + ts_ring = new TimeseriesRing(this); if(ts_ring && ts_ring->isTimeToInsert()) { NetworkInterfaceTsPoint *pt = new NetworkInterfaceTsPoint(); @@ -6834,11 +6834,12 @@ void NetworkInterface::makeTsPoint(NetworkInterfaceTsPoint *pt) { /* *************************************** */ void NetworkInterface::tsLua(lua_State* vm) { - if(!ts_ring || !TimeSeriesRing::isRingEnabled(ntop->getPrefs())) { + if(!ts_ring || !TimeseriesRing::isRingEnabled(ntop->getPrefs())) { /* Use real time data */ NetworkInterfaceTsPoint pt; + makeTsPoint(&pt); - TimeSeriesRing::luaSinglePoint(vm, this, &pt); + TimeseriesRing::luaSinglePoint(vm, this, &pt); } else ts_ring->lua(vm); } diff --git a/src/TimeSeriesRing.cpp b/src/TimeSeriesRing.cpp deleted file mode 100644 index 8f78ae8d83..0000000000 --- a/src/TimeSeriesRing.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * - * (C) 2013-18 - ntop.org - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include "ntop_includes.h" - -class TsRingStatus { - public: - TimeseriesPoint **ts_points; - u_int8_t max_points, available_points, point_idx; - u_int8_t num_steps, cur_steps; - - TsRingStatus(u_int8_t, u_int8_t); - ~TsRingStatus(); - - void insert(TimeseriesPoint *pt, time_t when); - void lua(lua_State* vm, NetworkInterface *iface); - inline bool isTimeToInsert() { return(++cur_steps >= num_steps); } -}; - -/* *************************************** */ - -TsRingStatus::TsRingStatus(u_int8_t max_points, u_int8_t num_steps) { - point_idx = available_points = 0; - cur_steps = 0; - - this->max_points = max_points; - this->ts_points = new TimeseriesPoint*[max_points](); - this->num_steps = num_steps; -} - -/* *************************************** */ - -TsRingStatus::~TsRingStatus() { - delete[] ts_points; -} - -/* *************************************** */ - -void TsRingStatus::insert(TimeseriesPoint *pt, time_t when) { - TimeseriesPoint *target = ts_points[point_idx]; - - if(target) delete target; - target = pt; - target->timestamp = when; - ts_points[point_idx] = target; - - point_idx = (point_idx + 1) % max_points; - cur_steps = 0; - - /* -1 because 1 point is for buffering */ - available_points = min(available_points + 1, max_points - 1); -} - -/* *************************************** */ - -void TsRingStatus::lua(lua_State* vm, NetworkInterface *iface) { - int idx = point_idx - available_points; - - if(idx < 0) - idx += max_points; - - lua_newtable(vm); - - for(int i=0; i < available_points; i++) { - TimeseriesPoint *pt = ts_points[idx]; - - if(pt) { - lua_newtable(vm); - - /* Process Point */ - lua_push_int_table_entry(vm, "instant", pt->timestamp); - pt->lua(vm, iface); - - lua_rawseti(vm, -2, i + 1); - } - - idx = (idx + 1) % max_points; - } -} - -/* *************************************** */ - -TimeSeriesRing::TimeSeriesRing(NetworkInterface *iface) { - this->iface = iface; - status = status_shadow = NULL; - - u_int8_t num_slots = ntop->getPrefs()->getNumTsSlots(); - - if(num_slots > 0) - status = new TsRingStatus(num_slots, ntop->getPrefs()->getNumTsSteps()); -} - -/* *************************************** */ - -TimeSeriesRing::~TimeSeriesRing() { - if(status) delete status; - if(status_shadow) delete status_shadow; -} - -/* *************************************** */ - -bool TimeSeriesRing::isTimeToInsert() { - u_int8_t num_slots = ntop->getPrefs()->getNumTsSlots(); - - if(status_shadow) { - delete status_shadow; - status_shadow = NULL; - } - - /* Number of slots can change at runtime due via user gui */ - if((!status && (num_slots > 0)) || (status && (num_slots != status->max_points))) { - TsRingStatus *new_status = NULL; - - if(num_slots > 0) - new_status = new TsRingStatus(num_slots, ntop->getPrefs()->getNumTsSteps()); - - status_shadow = status; - status = new_status; - } - - if(status) - return status->isTimeToInsert(); - - return false; -} - -/* *************************************** */ - -void TimeSeriesRing::insert(TimeseriesPoint *pt, time_t when) { - if(status) - status->insert(pt, when); -} - -/* *************************************** */ - -void TimeSeriesRing::lua(lua_State* vm) { - if(!status) - lua_pushnil(vm); - else - status->lua(vm, iface); -} - -/* *************************************** */ - -/* NOTE: same format as TsRingStatus::lua */ -void TimeSeriesRing::luaSinglePoint(lua_State* vm, NetworkInterface *iface, TimeseriesPoint *pt) { - lua_newtable(vm); - - lua_newtable(vm); - lua_push_int_table_entry(vm, "instant", time(0)); - pt->lua(vm, iface); - lua_rawseti(vm, -2, 1); -} diff --git a/src/TimeSeriesExporter.cpp b/src/TimeseriesExporter.cpp similarity index 93% rename from src/TimeSeriesExporter.cpp rename to src/TimeseriesExporter.cpp index b194950ada..23eed16517 100644 --- a/src/TimeSeriesExporter.cpp +++ b/src/TimeseriesExporter.cpp @@ -37,7 +37,7 @@ Start Chronograf $ chronograf */ -TimeSeriesExporter::TimeSeriesExporter(NetworkInterface *_if) { +TimeseriesExporter::TimeseriesExporter(NetworkInterface *_if) { fd = -1, iface = _if, num_cached_entries = 0, dbCreated = false; cursize = num_exports = 0; @@ -53,13 +53,13 @@ TimeSeriesExporter::TimeSeriesExporter(NetworkInterface *_if) { /* ******************************************************* */ -TimeSeriesExporter::~TimeSeriesExporter() { +TimeseriesExporter::~TimeseriesExporter() { flush(); } /* ******************************************************* */ -void TimeSeriesExporter::createDump() { +void TimeseriesExporter::createDump() { flushTime = time(NULL) + CONST_INFLUXDB_FLUSH_TIME; cursize = 0; @@ -89,7 +89,7 @@ void TimeSeriesExporter::createDump() { /* ******************************************************* */ -void TimeSeriesExporter::exportData(char *data, bool do_lock) { +void TimeseriesExporter::exportData(char *data, bool do_lock) { if(do_lock) m.lock(__FILE__, __LINE__); if(fd == -1) @@ -117,7 +117,7 @@ void TimeSeriesExporter::exportData(char *data, bool do_lock) { /* ******************************************************* */ -void TimeSeriesExporter::flush() { +void TimeseriesExporter::flush() { m.lock(__FILE__, __LINE__); if(fd != -1) { diff --git a/src/TimeseriesRing.cpp b/src/TimeseriesRing.cpp new file mode 100644 index 0000000000..47acb06b27 --- /dev/null +++ b/src/TimeseriesRing.cpp @@ -0,0 +1,97 @@ +/* + * + * (C) 2013-18 - ntop.org + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "ntop_includes.h" + +/* *************************************** */ + +TimeseriesRing::TimeseriesRing(NetworkInterface *iface) { + this->iface = iface; + status = status_shadow = NULL; + + u_int8_t num_slots = ntop->getPrefs()->getNumTsSlots(); + + if(num_slots > 0) + status = new TimeseriesRingStatus(num_slots, ntop->getPrefs()->getNumTsSteps()); +} + +/* *************************************** */ + +TimeseriesRing::~TimeseriesRing() { + if(status) delete status; + if(status_shadow) delete status_shadow; +} + +/* *************************************** */ + +bool TimeseriesRing::isTimeToInsert() { + u_int8_t num_slots = ntop->getPrefs()->getNumTsSlots(); + + if(status_shadow) { + delete status_shadow; + status_shadow = NULL; + } + + /* Number of slots can change at runtime due via user gui */ + if((!status && (num_slots > 0)) || (status && (num_slots != status->max_points))) { + TimeseriesRingStatus *new_status = NULL; + + if(num_slots > 0) + new_status = new TimeseriesRingStatus(num_slots, ntop->getPrefs()->getNumTsSteps()); + + status_shadow = status; + status = new_status; + } + + if(status) + return status->isTimeToInsert(); + + return false; +} + +/* *************************************** */ + +void TimeseriesRing::insert(TimeseriesPoint *pt, time_t when) { + if(status) + status->insert(pt, when); +} + +/* *************************************** */ + +void TimeseriesRing::lua(lua_State* vm) { + if(!status) + lua_pushnil(vm); + else + status->lua(vm, iface); +} + +/* *************************************** */ + +/* NOTE: same format as TimeseriesRingStatus::lua */ +void TimeseriesRing::luaSinglePoint(lua_State* vm, NetworkInterface *iface, + TimeseriesPoint *pt) { + lua_newtable(vm); + + lua_newtable(vm); + lua_push_int_table_entry(vm, "instant", time(0)); + pt->lua(vm, iface); + lua_rawseti(vm, -2, 1); +} diff --git a/src/TimeseriesRingStatus.cpp b/src/TimeseriesRingStatus.cpp new file mode 100644 index 0000000000..3f767dd6ea --- /dev/null +++ b/src/TimeseriesRingStatus.cpp @@ -0,0 +1,84 @@ +/* + * + * (C) 2013-18 - ntop.org + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "ntop_includes.h" + +/* *************************************** */ + +TimeseriesRingStatus::TimeseriesRingStatus(u_int8_t max_points, u_int8_t num_steps) { + point_idx = available_points = 0; + cur_steps = 0; + + this->max_points = max_points; + this->ts_points = new TimeseriesPoint*[max_points](); + this->num_steps = num_steps; +} + +/* *************************************** */ + +TimeseriesRingStatus::~TimeseriesRingStatus() { + delete[] ts_points; +} + +/* *************************************** */ + +void TimeseriesRingStatus::insert(TimeseriesPoint *pt, time_t when) { + TimeseriesPoint *target = ts_points[point_idx]; + + if(target) delete target; + target = pt; + target->timestamp = when; + ts_points[point_idx] = target; + + point_idx = (point_idx + 1) % max_points; + cur_steps = 0; + + /* -1 because 1 point is for buffering */ + available_points = min(available_points + 1, max_points - 1); +} + +/* *************************************** */ + +void TimeseriesRingStatus::lua(lua_State* vm, NetworkInterface *iface) { + int idx = point_idx - available_points; + + if(idx < 0) + idx += max_points; + + lua_newtable(vm); + + for(int i=0; i < available_points; i++) { + TimeseriesPoint *pt = ts_points[idx]; + + if(pt) { + lua_newtable(vm); + + /* Process Point */ + lua_push_int_table_entry(vm, "instant", pt->timestamp); + pt->lua(vm, iface); + + lua_rawseti(vm, -2, i + 1); + } + + idx = (idx + 1) % max_points; + } +} +