sensor: re-sample pressure data and perform lazy insertions to reduce DB overhead
[platform/core/context/context-provider.git] / src / sensor / pressure / PressureLogger.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sqlite3.h>
18 #include <SensorRecorderTypes.h>
19 #include "../TypesInternal.h"
20 #include "../ClientInfo.h"
21 #include "../TimeUtil.h"
22 #include "PressureLogger.h"
23
24 #define SAMPLING_INTERVAL       60000
25 #define BATCH_LATENCY           INT_MAX
26
27 #define RESAMPLING_INTERVAL     20000
28 #define CACHE_LIMIT                     20
29
30 using namespace ctx;
31
32 PressureLogger::PressureLogger()
33 {
34         setSensor(PRESSURE_SENSOR);
35         setPowerSave(false);
36         setSamplingInterval(SAMPLING_INTERVAL);
37         setBatchLatency(BATCH_LATENCY);
38
39         /* Create the log table */
40         executeQuery(
41                         "CREATE TABLE IF NOT EXISTS " PRESSURE_RECORD " (" \
42                                 KEY_UNIV_TIME " INTEGER NOT NULL PRIMARY KEY, " \
43                                 KEY_PRESSURE " REAL NOT NULL" \
44                         ")");
45
46         ClientInfo clientInfo;
47         if (clientInfo.exist(SUBJ_SENSOR_PRESSURE))
48                 start();
49 }
50
51 PressureLogger::~PressureLogger()
52 {
53         stop();
54 }
55
56 bool PressureLogger::start()
57 {
58         IF_FAIL_RETURN_TAG(!isRunning(), true, _D, "Started already");
59         _I(GREEN("Start to record"));
60
61         __lastEventTime = 0;
62         __cacheCount = 0;
63         __resetInsertionQuery();
64
65         return listen();
66 }
67
68 void PressureLogger::stop()
69 {
70         IF_FAIL_VOID_TAG(isRunning(), _D, "Stopped already");
71         _I(GREEN("Stop recording"));
72
73         unlisten();
74         flushCache(true);
75 }
76
77 void PressureLogger::flushCache(bool force)
78 {
79         IF_FAIL_VOID(force || __cacheCount > CACHE_LIMIT);
80
81         __insertionQuery.resize(__insertionQuery.size() - 1);
82         if (__insertionQuery.at(__insertionQuery.size() - 1) == ')')
83                 executeQuery(__insertionQuery.c_str());
84
85         __cacheCount = 0;
86         __resetInsertionQuery();
87 }
88
89 void PressureLogger::onEvent(sensor_data_t *eventData)
90 {
91         uint64_t eventTime = TimeUtil::getTime(eventData->timestamp);
92         __record(eventData->values[0], eventTime);
93         removeExpired(SUBJ_SENSOR_PRESSURE, PRESSURE_RECORD, KEY_UNIV_TIME);
94 }
95
96 void PressureLogger::__record(float pressure, uint64_t eventTime)
97 {
98         IF_FAIL_VOID(eventTime - __lastEventTime >= RESAMPLING_INTERVAL);
99
100         char buffer[64];
101         g_snprintf(buffer, sizeof(buffer), "(%llu, %.5f),", eventTime, pressure);
102         _D("[%u] %s", __cacheCount, buffer);
103
104         __insertionQuery += buffer;
105         __lastEventTime = eventTime;
106         ++__cacheCount;
107
108         flushCache();
109 }
110
111 void PressureLogger::__resetInsertionQuery()
112 {
113         __insertionQuery =
114                 "INSERT INTO " PRESSURE_RECORD \
115                         " (" KEY_UNIV_TIME ", " KEY_PRESSURE ") VALUES ";
116 }