Commit 4d174c35884d2ad6cc44311e0ce2402da78f4eb7

Authored by Viacheslav Klimov
2 parents e2b455e8 3624066b

Merge remote-tracking branch 'thingsboard/master'

... ... @@ -36,8 +36,56 @@ interface AggData {
36 36 aggValue: any;
37 37 }
38 38
39   -interface AggregationMap {
40   - [key: string]: Map<number, AggData>;
  39 +class AggDataMap {
  40 + rangeChanged = false;
  41 + private minTs = Number.MAX_SAFE_INTEGER;
  42 + private map = new Map<number, AggData>();
  43 +
  44 + set(ts: number, data: AggData) {
  45 + if (ts < this.minTs) {
  46 + this.rangeChanged = true;
  47 + this.minTs = ts;
  48 + }
  49 + this.map.set(ts, data);
  50 + }
  51 +
  52 + get(ts: number): AggData {
  53 + return this.map.get(ts);
  54 + }
  55 +
  56 + delete(ts: number) {
  57 + this.map.delete(ts);
  58 + }
  59 +
  60 + forEach(callback: (value: AggData, key: number, map: Map<number, AggData>) => void, thisArg?: any) {
  61 + this.map.forEach(callback, thisArg);
  62 + }
  63 +
  64 + size(): number {
  65 + return this.map.size;
  66 + }
  67 +}
  68 +
  69 +class AggregationMap {
  70 + aggMap: {[key: string]: AggDataMap} = {};
  71 +
  72 + detectRangeChanged(): boolean {
  73 + let changed = false;
  74 + for (const key of Object.keys(this.aggMap)) {
  75 + const aggDataMap = this.aggMap[key];
  76 + if (aggDataMap.rangeChanged) {
  77 + changed = true;
  78 + aggDataMap.rangeChanged = false;
  79 + }
  80 + }
  81 + return changed;
  82 + }
  83 +
  84 + clearRangeChangedFlags() {
  85 + for (const key of Object.keys(this.aggMap)) {
  86 + this.aggMap[key].rangeChanged = false;
  87 + }
  88 + }
41 89 }
42 90
43 91 declare type AggFunction = (aggData: AggData, value?: any) => void;
... ... @@ -170,7 +218,7 @@ export class DataAggregator {
170 218 updateIntervalScheduledTime = false;
171 219 }
172 220 if (update) {
173   - this.aggregationMap = {};
  221 + this.aggregationMap = new AggregationMap();
174 222 this.updateAggregatedData(data.data);
175 223 } else {
176 224 this.aggregationMap = this.processAggregatedData(data.data);
... ... @@ -178,12 +226,17 @@ export class DataAggregator {
178 226 if (updateIntervalScheduledTime) {
179 227 this.intervalScheduledTime = this.utils.currentPerfTime();
180 228 }
  229 + this.aggregationMap.clearRangeChangedFlags();
181 230 this.onInterval(history, detectChanges);
182 231 } else {
183 232 this.updateAggregatedData(data.data);
184 233 if (history) {
185 234 this.intervalScheduledTime = this.utils.currentPerfTime();
186 235 this.onInterval(history, detectChanges);
  236 + } else {
  237 + if (this.aggregationMap.detectRangeChanged()) {
  238 + this.onInterval(false, detectChanges, true);
  239 + }
187 240 }
188 241 }
189 242 }
... ... @@ -203,7 +256,7 @@ export class DataAggregator {
203 256 }
204 257 }
205 258
206   - private onInterval(history?: boolean, detectChanges?: boolean) {
  259 + private onInterval(history?: boolean, detectChanges?: boolean, rangeChanged?: boolean) {
207 260 const now = this.utils.currentPerfTime();
208 261 this.elapsed += now - this.intervalScheduledTime;
209 262 this.intervalScheduledTime = now;
... ... @@ -211,9 +264,10 @@ export class DataAggregator {
211 264 clearTimeout(this.intervalTimeoutHandle);
212 265 this.intervalTimeoutHandle = null;
213 266 }
  267 + const intervalTimeout = rangeChanged ? this.aggregationTimeout - this.elapsed : this.aggregationTimeout;
214 268 if (!history) {
215 269 const delta = Math.floor(this.elapsed / this.subsTw.aggregation.interval);
216   - if (delta || !this.data) {
  270 + if (delta || !this.data || rangeChanged) {
217 271 const tickTs = delta * this.subsTw.aggregation.interval;
218 272 if (this.subsTw.quickInterval) {
219 273 const currentDate = this.getCurrentTime();
... ... @@ -234,7 +288,7 @@ export class DataAggregator {
234 288 this.updatedData = false;
235 289 }
236 290 if (!history) {
237   - this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), this.aggregationTimeout);
  291 + this.intervalTimeoutHandle = setTimeout(this.onInterval.bind(this), intervalTimeout);
238 292 }
239 293 }
240 294
... ... @@ -242,8 +296,8 @@ export class DataAggregator {
242 296 this.tsKeyNames.forEach((key) => {
243 297 this.dataBuffer[key] = [];
244 298 });
245   - for (const key of Object.keys(this.aggregationMap)) {
246   - const aggKeyData = this.aggregationMap[key];
  299 + for (const key of Object.keys(this.aggregationMap.aggMap)) {
  300 + const aggKeyData = this.aggregationMap.aggMap[key];
247 301 let keyData = this.dataBuffer[key];
248 302 aggKeyData.forEach((aggData, aggTimestamp) => {
249 303 if (aggTimestamp <= this.startTs) {
... ... @@ -300,12 +354,12 @@ export class DataAggregator {
300 354
301 355 private processAggregatedData(data: SubscriptionData): AggregationMap {
302 356 const isCount = this.subsTw.aggregation.type === AggregationType.COUNT;
303   - const aggregationMap: AggregationMap = {};
  357 + const aggregationMap = new AggregationMap();
304 358 for (const key of Object.keys(data)) {
305   - let aggKeyData = aggregationMap[key];
  359 + let aggKeyData = aggregationMap.aggMap[key];
306 360 if (!aggKeyData) {
307   - aggKeyData = new Map<number, AggData>();
308   - aggregationMap[key] = aggKeyData;
  361 + aggKeyData = new AggDataMap();
  362 + aggregationMap.aggMap[key] = aggKeyData;
309 363 }
310 364 const keyData = data[key];
311 365 keyData.forEach((kvPair) => {
... ... @@ -326,10 +380,10 @@ export class DataAggregator {
326 380 private updateAggregatedData(data: SubscriptionData) {
327 381 const isCount = this.subsTw.aggregation.type === AggregationType.COUNT;
328 382 for (const key of Object.keys(data)) {
329   - let aggKeyData = this.aggregationMap[key];
  383 + let aggKeyData = this.aggregationMap.aggMap[key];
330 384 if (!aggKeyData) {
331   - aggKeyData = new Map<number, AggData>();
332   - this.aggregationMap[key] = aggKeyData;
  385 + aggKeyData = new AggDataMap();
  386 + this.aggregationMap.aggMap[key] = aggKeyData;
333 387 }
334 388 const keyData = data[key];
335 389 keyData.forEach((kvPair) => {
... ... @@ -374,4 +428,3 @@ export class DataAggregator {
374 428 }
375 429
376 430 }
377   -
... ...