Skip to content

Commit 1044cac

Browse files
author
Enric Sala
committed
Improve the performance of the series builder
The line protocol generation method is now self contained, it no longer calls the point builder to format each sample
1 parent c7c454f commit 1044cac

File tree

1 file changed

+63
-19
lines changed

1 file changed

+63
-19
lines changed

influxdb-client/Series.m

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
% Add a tag
1717
function obj = tag(obj, key, value)
18-
obj.Tags{end + 1} = struct('key', key, 'value', value);
18+
obj.Tags{end + 1} = [key '=' value];
1919
end
2020

2121
% Add multiple tags at once
@@ -58,6 +58,8 @@
5858
function lines = toLine(obj, precision)
5959
time_length = length(obj.Time);
6060
field_lengths = unique(cellfun(@(x) length(x.value), obj.Fields));
61+
62+
% Make sure the dimensions match
6163
assert(~isempty(obj.Time), ...
6264
'toLine:emptyTime', 'the time vector cannot be empty');
6365
assert(~isempty(field_lengths), ...
@@ -66,36 +68,78 @@
6668
'toLine:sizeMismatch', 'all fields must have the same length');
6769
assert(time_length == field_lengths || time_length == 0, ...
6870
'toLine:sizeMismatch', 'time and fields must have the same length');
69-
builder = java.lang.StringBuilder();
71+
72+
% Obtain the time precision scale
73+
if nargin < 2, precision = 'ms'; end
74+
scale = obj.timeScale(precision);
75+
timestamp = int64(scale * posixtime(obj.Time));
76+
77+
% Create a line for each sample
78+
prefix = [strjoin([{obj.Name}, obj.Tags], ','), ' '];
79+
builder = '';
7080
for i = 1:field_lengths
71-
point = Point(obj.Name);
72-
for t = 1:length(obj.Tags)
73-
tag = obj.Tags{t};
74-
point.tag(tag.key, tag.value);
75-
end
81+
values = '';
7682
for f = 1:length(obj.Fields)
7783
field = obj.Fields{f};
7884
name = field.key;
7985
value = field.value;
8086
if iscell(value)
81-
point.field(name, value{i});
87+
str = obj.fieldFmt(name, value{i});
8288
else
83-
point.field(name, value(i));
89+
str = obj.fieldFmt(name, value(i));
90+
end
91+
if ~isempty(str)
92+
values = [values, str, ','];
8493
end
8594
end
86-
point.time(obj.Time(i));
87-
if nargin < 2
88-
line = point.toLine();
89-
else
90-
line = point.toLine(precision);
95+
if ~isempty(values)
96+
values = values(1:end-1);
97+
time = sprintf(' %i', timestamp(i));
98+
builder = [builder, prefix, values, time, newline];
9199
end
92-
if ~isempty(line)
93-
builder.append(line);
94-
builder.append(newline);
100+
end
101+
lines = builder(1:end-1);
102+
end
103+
end
104+
105+
methods(Static, Access = private)
106+
% Format a field
107+
function str = fieldFmt(key, value)
108+
if isfloat(value)
109+
if ~isempty(value) && isfinite(value)
110+
str = sprintf('%s=%.8g', key, value);
111+
else
112+
str = '';
95113
end
114+
elseif isinteger(value)
115+
str = sprintf('%s=%ii', key, value);
116+
elseif ischar(value)
117+
str = [key '="' value '"'];
118+
elseif islogical(value)
119+
str = [key '=' iif(value, 'true', 'false')];
120+
else
121+
error('unsupported value type');
122+
end
123+
end
124+
125+
% Otain the scale for a precision
126+
function scale = timeScale(precision)
127+
switch precision
128+
case 'ns'
129+
scale = 1000000000;
130+
case 'u'
131+
scale = 1000000;
132+
case 'ms'
133+
scale = 1000;
134+
case 's'
135+
scale = 1;
136+
case 'm'
137+
scale = 1 / 60;
138+
case 'h'
139+
scale = 1 / 3600;
140+
otherwise
141+
error('precision:unknown', '"%s" is not a valid precision', precision);
96142
end
97-
builder.deleteCharAt(int32(builder.length() - 1));
98-
lines = char(builder.toString());
99143
end
100144
end
101145

0 commit comments

Comments
 (0)