Skip to content

Commit

Permalink
Fixes esnet#141 (Timeseries with names containing dots are not compat…
Browse files Browse the repository at this point in the history
…ible with fieldSpecs)
  • Loading branch information
Lukas Laag committed Aug 28, 2019
1 parent 551f8af commit 8510e87
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 24 deletions.
17 changes: 5 additions & 12 deletions packages/pond/src/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,7 @@ import {
sum
} from "./functions";

/**
* Convert the `fieldspec` into a list if it is not already.
*/
function fieldAsArray(field: string | string[]): string[] {
if (_.isArray(field)) {
return field;
} else if (_.isString(field)) {
return field.split(".");
}
}
import util from "./util";

/**
* A `Collection` holds a ordered (but not sorted) list of `Event`s and provides the
Expand Down Expand Up @@ -502,9 +493,11 @@ export class Collection<T extends Key> extends Base {
/**
* Sorts the `Collection` using the value referenced by
* the `field`.
* `fieldSeparator` lets one specify the separator used in the `field spec`
* (defaults to ".")
*/
public sort(field: string | string[]): Collection<T> {
const fs = fieldAsArray(field);
public sort(field: string | string[], fieldSeparator: string = "."): Collection<T> {
const fs = util.fieldAsArray(field, fieldSeparator);
const sorted = Immutable.List<Event<T>>(
this._events.sortBy(event => {
return event.get(fs);
Expand Down
16 changes: 12 additions & 4 deletions packages/pond/src/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,11 @@ export class Event<T extends Key = Time> extends Base {
* ```
*
* Note: the default `field` is "value".
* `fieldSeparator` lets one specify the separator used in the `field spec`
* (defaults to ".")
*/
public get(field: string | string[] = "value"): any {
const f = util.fieldAsArray(field);
public get(field: string | string[] = "value", fieldSeparator: string = "."): any {
const f = util.fieldAsArray(field, fieldSeparator);
return this.getData().getIn(f);
}

Expand All @@ -530,9 +532,15 @@ export class Event<T extends Key = Time> extends Base {
* const modified = e.set("name", "fred");
* modified.toString() // {"time": 1487983075328, "data": {"name":"fred"} }
* ```
* `fieldSeparator` lets one specify the separator used in the `field spec`
* (defaults to ".")
*/
public set(field: string | string[] = "value", value: any): Event<T> {
const f = util.fieldAsArray(field);
public set(
field: string | string[] = "value",
value: any,
fieldSeparator: string = "."
): Event<T> {
const f = util.fieldAsArray(field, fieldSeparator);
return new Event<T>(this.getKey(), this.getData().setIn(f, value));
}

Expand Down
10 changes: 6 additions & 4 deletions packages/pond/src/fill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { FillMethod, FillOptions } from "./types";
export class Fill<T extends Key> extends Processor<T, T> {
// Options
private _fieldSpec: string[];
private _fieldSeparator: string;
private _method: FillMethod;
private _limit: number | null;

Expand All @@ -39,10 +40,11 @@ export class Fill<T extends Key> extends Processor<T, T> {
constructor(options: FillOptions) {
super();

const { fieldSpec, method = FillMethod.Pad, limit = null } = options;
const { fieldSpec, fieldSeparator = ".", method = FillMethod.Pad, limit = null } = options;

// Options
this._fieldSpec = _.isString(fieldSpec) ? [fieldSpec] : fieldSpec;
this._fieldSeparator = fieldSeparator;
this._method = method;
this._limit = limit;

Expand All @@ -66,7 +68,7 @@ export class Fill<T extends Key> extends Processor<T, T> {
let newData = data;

for (const path of this._fieldSpec) {
const fieldPath = util.fieldAsArray(path);
const fieldPath = util.fieldAsArray(path, this._fieldSeparator);
const pathKey = fieldPath.join(":");

// initialize a counter for this column
Expand Down Expand Up @@ -122,7 +124,7 @@ export class Fill<T extends Key> extends Processor<T, T> {
*/
isValidLinearEvent(event: Event<T>) {
let valid = true;
const fieldPath = util.fieldAsArray(this._fieldSpec[0]);
const fieldPath = util.fieldAsArray(this._fieldSpec[0], this._fieldSeparator);

// Detect path that doesn't exist
if (!event.getData().hasIn(fieldPath)) {
Expand Down Expand Up @@ -227,7 +229,7 @@ export class Fill<T extends Key> extends Processor<T, T> {
// new array of interpolated events for each field path
const newEvents: Array<Event<T>> = [];

const fieldPath = util.fieldAsArray(this._fieldSpec[0]);
const fieldPath = util.fieldAsArray(this._fieldSpec[0], this._fieldSeparator);

// setup done, loop through the events
for (let i = 0; i < events.length; i++) {
Expand Down
7 changes: 5 additions & 2 deletions packages/pond/src/rate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,24 @@ import { RateOptions } from "./types";
* ```
* Options:
* * `fieldSpec` - the field to calculate the rate on
* * `fieldSeparator` - the separator used in the `fieldSpec` (defaults to ".")
* * `allowNegative` - allow emit of negative rates
*/
export class Rate<T extends Key> extends Processor<T, TimeRange> {
// Internal state
private fieldSpec: string[];
private fieldSeparator: string;
private allowNegative: boolean;

private previous: Event<T>;

constructor(options: RateOptions) {
super();
const { fieldSpec, allowNegative = false } = options;
const { fieldSpec, allowNegative = false, fieldSeparator = "." } = options;

// Options
this.fieldSpec = _.isString(fieldSpec) ? [fieldSpec] : fieldSpec;
this.fieldSeparator = fieldSeparator;
this.allowNegative = allowNegative;

// Previous event
Expand Down Expand Up @@ -93,7 +96,7 @@ export class Rate<T extends Key> extends Processor<T, TimeRange> {
const deltaTime = (currentTime - previousTime) / 1000;

this.fieldSpec.forEach(path => {
const fieldPath = util.fieldAsArray(path);
const fieldPath = util.fieldAsArray(path, this.fieldSeparator);
const ratePath = fieldPath.slice();
ratePath[ratePath.length - 1] += "_rate";

Expand Down
4 changes: 4 additions & 0 deletions packages/pond/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,22 +167,26 @@ export interface CollapseOptions {
/**
* Option object passed to the `rate()` function:
* * fieldSpec - the field to calculate the rate on
* * fieldSeparator - the separator used in the `fieldSpec` (defaults to ".")
* * allowNegative - allow emit of negative rates
*/
export interface RateOptions {
fieldSpec: string | string[];
fieldSeparator?: string;
allowNegative?: boolean;
}

/**
* Options object expected by the `fill()` function:
* * `fieldSpec` - the field to fill
* * `fieldSeparator` - the separator used in the `fieldSpec` (defaults to ".")
* * `method` - the interpolation method, one of
* `FillMethod.Hold`, `FillMethod.Pad` or `FillMethod.Linear`
* * `limit` - the number of missing values to fill before giving up
*/
export interface FillOptions {
fieldSpec: string | string[];
fieldSeparator?: string;
method?: FillMethod;
limit?: number;
}
Expand Down
6 changes: 4 additions & 2 deletions packages/pond/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,12 +310,14 @@ function dataFromArg(

/**
* Convert the `field spec` into a list if it is not already.
* `fieldSeparator` lets one specify the separator used in the `field spec`
* (defaults to ".")
*/
function fieldAsArray(field: string | string[]): string[] {
function fieldAsArray(field: string | string[], fieldSeparator: string = "."): string[] {
if (_.isArray(field)) {
return field;
} else if (_.isString(field)) {
return field.split(".");
return field.split(fieldSeparator);
}
}

Expand Down

0 comments on commit 8510e87

Please sign in to comment.