Skip to content

Commit 780bae1

Browse files
soudrugvlastahajek
authored andcommitted
chore: point strings optimization
1 parent e82eeb7 commit 780bae1

File tree

8 files changed

+95
-51
lines changed

8 files changed

+95
-51
lines changed

src/InfluxData.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929

3030
void InfluxData::setTimestamp(long int seconds)
3131
{
32-
_timestamp = timeStampToString(seconds) + "000000000";
32+
_timestamp = timeStampToString(seconds,9);
33+
strcat(_timestamp, "000000000");
3334
}
3435

3536
String InfluxData::toString() const {

src/Options.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@ WriteOptions& WriteOptions::addDefaultTag(const String &name, const String &valu
3232
if(_defaultTags.length() > 0) {
3333
_defaultTags += ',';
3434
}
35-
_defaultTags += escapeKey(name);
35+
char *s = escapeKey(name);
36+
_defaultTags += s;
37+
delete [] s;
38+
s = escapeKey(value);
3639
_defaultTags += '=';
37-
_defaultTags += escapeKey(value);
40+
_defaultTags += s;
41+
delete [] s;
3842
return *this;
3943
}

src/Point.cpp

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,38 @@
2828
#include "Point.h"
2929
#include "util/helpers.h"
3030

31-
Point::Point(const String & measurement):
32-
_measurement(escapeKey(measurement, false)),
33-
_tags(""),
34-
_fields(""),
35-
_timestamp("")
31+
Point::Point(const String & measurement)
3632
{
33+
_measurement = escapeKey(measurement, false);
34+
_timestamp = nullptr;
35+
}
3736

37+
Point::~Point() {
38+
delete [] _measurement;
39+
delete [] _timestamp;
3840
}
3941

4042
void Point::addTag(const String &name, String value) {
4143
if(_tags.length() > 0) {
4244
_tags += ',';
4345
}
44-
_tags += escapeKey(name);
46+
char *s = escapeKey(name);
47+
_tags += s;
48+
delete [] s;
4549
_tags += '=';
46-
_tags += escapeKey(value);
50+
s = escapeKey(value);
51+
_tags += s;
52+
delete [] s;
4753
}
4854

4955
void Point::addField(const String &name, long long value) {
50-
char buff[50];
56+
char buff[23];
5157
snprintf(buff, 50, "%lld", value);
5258
putField(name, String(buff)+"i");
5359
}
5460

5561
void Point::addField(const String &name, unsigned long long value) {
56-
char buff[50];
62+
char buff[23];
5763
snprintf(buff, 50, "%llu", value);
5864
putField(name, String(buff)+"i");
5965
}
@@ -110,7 +116,9 @@ void Point::putField(const String &name, const String &value) {
110116
if(_fields.length() > 0) {
111117
_fields += ',';
112118
}
113-
_fields += escapeKey(name);
119+
char *s = escapeKey(name);
120+
_fields += s;
121+
delete [] s;
114122
_fields += '=';
115123
_fields += value;
116124
}
@@ -121,7 +129,7 @@ String Point::toLineProtocol(const String &includeTags) const {
121129

122130
String Point::createLineProtocol(const String &incTags) const {
123131
String line;
124-
line.reserve(_measurement.length() + 1 + incTags.length() + 1 + _tags.length() + 1 + _fields.length() + 1 + _timestamp.length());
132+
line.reserve(strLen(_measurement) + 1 + incTags.length() + 1 + _tags.length() + 1 + _fields.length() + 1 + strLen(_timestamp));
125133
line += _measurement;
126134
if(incTags.length()>0) {
127135
line += ",";
@@ -160,22 +168,32 @@ void Point::setTime(WritePrecision precision) {
160168
setTime(getTimeStamp(&tv,0));
161169
break;
162170
case WritePrecision::NoTime:
163-
_timestamp = "";
171+
setTime((char *)nullptr);
164172
break;
165173
}
166174
}
167175

168176
void Point::setTime(unsigned long long timestamp) {
169-
_timestamp = timeStampToString(timestamp);
177+
setTime(timeStampToString(timestamp));
178+
}
179+
180+
void Point::setTime(const String &timestamp) {
181+
setTime(cloneStr(timestamp.c_str()));
182+
}
183+
184+
void Point::setTime(const char *timestamp) {
185+
setTime(cloneStr(timestamp));
170186
}
171187

172-
void Point::setTime(const String &timestamp) {
173-
_timestamp = timestamp;
188+
void Point::setTime(char *timestamp) {
189+
delete [] _timestamp;
190+
timestamp = timestamp;
174191
}
175192

176193
void Point::clearFields() {
177194
_fields = (char *)nullptr;
178-
_timestamp = (char *)nullptr;
195+
delete [] _timestamp;
196+
_timestamp = nullptr;
179197
}
180198

181199
void Point:: clearTags() {

src/Point.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class Point {
3939
friend class InfluxDBClient;
4040
public:
4141
Point(const String &measurement);
42+
virtual ~Point();
4243
// Adds string tag
4344
void addTag(const String &name, String value);
4445
// Add field with various types
@@ -62,6 +63,8 @@ friend class InfluxDBClient;
6263
void setTime(unsigned long long timestamp);
6364
// Set timestamp in offset since epoch (1.1.1970 00:00:00). Correct precision must be set InfluxDBClient::setWriteOptions.
6465
void setTime(const String &timestamp);
66+
// Set timestamp in offset since epoch (1.1.1970 00:00:00). Correct precision must be set InfluxDBClient::setWriteOptions.
67+
void setTime(const char *timestamp);
6568
// Clear all fields. Usefull for reusing point
6669
void clearFields();
6770
// Clear tags
@@ -71,19 +74,21 @@ friend class InfluxDBClient;
7174
// True if a point contains at least one tag
7275
bool hasTags() const { return _tags.length() > 0; }
7376
// True if a point contains timestamp
74-
bool hasTime() const { return _timestamp.length() > 0; }
77+
bool hasTime() const { return strLen(_timestamp) > 0; }
7578
// Creates line protocol with optionally added tags
7679
String toLineProtocol(const String &includeTags = "") const;
7780
// returns current timestamp
7881
String getTime() const { return _timestamp; }
7982
protected:
80-
String _measurement;
83+
char *_measurement;
8184
String _tags;
8285
String _fields;
83-
String _timestamp;
86+
char *_timestamp;
8487
protected:
8588
// method for formating field into line protocol
8689
void putField(const String &name, const String &value);
90+
// set timestamp
91+
void setTime(char *timestamp);
8792
// Creates line protocol string
8893
String createLineProtocol(const String &incTags) const;
8994
};

src/util/helpers.cpp

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,36 +68,34 @@ unsigned long long getTimeStamp(struct timeval *tv, int secFracDigits) {
6868
return tsVal;
6969
}
7070

71-
String timeStampToString(unsigned long long timestamp) {
72-
static char buff[50];
73-
snprintf(buff, 50, "%llu", timestamp);
74-
return String(buff);
71+
char *timeStampToString(unsigned long long timestamp, int extraCharsSpace) {
72+
//22 is max long long string length (18)
73+
char *buff = new char[22+extraCharsSpace+1];
74+
snprintf(buff, 22, "%llu", timestamp);
75+
return buff;
7576
}
7677

77-
String escapeKey(const String &key, bool escapeEqual) {
78-
String ret;
79-
ret.reserve(key.length()+5); //5 is estimate of chars needs to escape,
78+
static char escapeChars[] = "=\r\n\t ,";
8079

81-
for (char c: key)
82-
{
83-
switch (c)
84-
{
85-
case '\r':
86-
case '\n':
87-
case '\t':
88-
case ' ':
89-
case ',':
90-
ret += '\\';
91-
break;
92-
case '=':
93-
if(escapeEqual) {
94-
ret += '\\';
95-
}
96-
break;
80+
char *escapeKey(const String &key, bool escapeEqual) {
81+
char c,*ret,*d,*s = (char *)key.c_str();
82+
int n = 0;
83+
while ((c = *s++)) {
84+
if(strchr(escapeEqual?escapeChars:escapeChars+1, c)) {
85+
n++;
9786
}
98-
ret += c;
9987
}
100-
return ret;
88+
ret = new char[key.length()+n+1];
89+
s = (char *)key.c_str();
90+
d = ret;
91+
while ((c = *s++)) {
92+
if (strchr(escapeEqual?escapeChars:escapeChars+1,c)) {
93+
*d++ = '\\';
94+
}
95+
*d++ = c;
96+
}
97+
*d = 0;
98+
return ret;
10199
}
102100

103101
String escapeValue(const char *value) {
@@ -175,3 +173,16 @@ uint8_t getNumLength(long long l) {
175173
} while(l);
176174
return c;
177175
}
176+
177+
char *cloneStr(const char *str) {
178+
char *ret = new char[strlen(str)+1];
179+
strcpy(ret, str);
180+
return ret;
181+
}
182+
183+
size_t strLen(const char *str) {
184+
if(!str) {
185+
return 0;
186+
}
187+
return strlen(str);
188+
}

src/util/helpers.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ void timeSync(const char *tzInfo, const char* ntpServer1, const char* ntpServer2
3939
unsigned long long getTimeStamp(struct timeval *tv, int secFracDigits = 3);
4040

4141
// Converts unsigned long long timestamp to String
42-
String timeStampToString(unsigned long long timestamp);
42+
char *timeStampToString(unsigned long long timestamp, int extraCharsSpace = 0);
4343

4444
// Escape invalid chars in measurement, tag key, tag value and field key
45-
String escapeKey(const String &key, bool escapeEqual = true);
45+
char *escapeKey(const String &key, bool escapeEqual = true);
4646

4747
// Escape invalid chars in field value
4848
String escapeValue(const char *value);
@@ -54,5 +54,10 @@ bool isValidID(const char *idString);
5454
const char *bool2string(bool val);
5555
// Returns number of digits
5656
uint8_t getNumLength(long long l);
57+
// Like strdup, but uses new
58+
char *cloneStr(const char *str);
59+
// Like strlen, but accepts nullptr
60+
size_t strLen(const char *str);
61+
5762

5863
#endif //_INFLUXDB_CLIENT_HELPERS_H

test/TestBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Point *TestBase::createPoint(const String &measurement) {
4343
return point;
4444
}
4545

46-
bool testAssertm(int line, bool state,String message) {
46+
bool testAssertm(int line, bool state, const String &message) {
4747
if(!state) {
4848
++TestBase::failures;
4949
Serial.printf("Assert failure line %d%s%s\n", line, message.length()>0?": ":"",message.c_str());

test/TestBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class TestBase {
5656
static Point *createPoint(const String &measurement);
5757
};
5858

59-
bool testAssertm(int line, bool state,String message);
59+
bool testAssertm(int line, bool state,const String &message);
6060
bool testAssert(int line, bool state);
6161

6262
#endif //_E2E_TEST_H_

0 commit comments

Comments
 (0)