From 39be4c53df0d996cd53f0b7c11d961142f8d33fc Mon Sep 17 00:00:00 2001 From: Dax Eckenberg Date: Mon, 18 Jul 2016 15:45:43 -0700 Subject: [PATCH] Issue-#4: Add support for saving state * added _traverse private method walks the binary tree calling _insert_centroid on each data node * added _insert_centroid private method simply inserts an existing object into the tree * added public load method takes an object and re-initializes state from that object --- tdigest.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tdigest.js b/tdigest.js index 1b5c2b8..4e9af22 100644 --- a/tdigest.js +++ b/tdigest.js @@ -30,6 +30,25 @@ function TDigest(delta, K, CX) { this.reset(); } +TDigest.prototype.load = function( tdObject ) { + // given a javascript object, re-initialize ourselves + // + // save: is not implemented as JSON.stringify(TDigest object) works just fine + // + + //clear & reload + this.centroids.clear(); + this._traverse(tdObject.centroids._root); + + // init all internal variables based on object + this.delta = tdObject.delta; + this.K = tdObject.K; + this.CX = tdObject.CX; + this.n = tdObject.n; + this.nreset = tdObject.nreset; + this.last_cumulate = tdObject.last_cumulate; +}; + TDigest.prototype.reset = function() { // prepare to digest new points. // @@ -141,6 +160,25 @@ TDigest.prototype.find_nearest = function(x) { } }; +TDigest.prototype._traverse = function(obj) { + if ( obj.left ) { + this._traverse(obj.left); + } + if ( obj.right ) { + this._traverse(obj.right); + } + if (obj.data) { + this._insert_centroid(obj.data); + } +} + +TDigest.prototype._insert_centroid = function(obj) { + // insert a centroid into the digest + // + this.centroids.insert(obj); + this.n += obj.n; +}; + TDigest.prototype._new_centroid = function(x, n, cumn) { // create and insert a new centroid into the digest (don't update // cumulatives). @@ -294,6 +332,8 @@ TDigest.prototype._percentile = function(p) { return undefined; } this._cumulate(true); // be sure cumns are exact + var min = this.centroids.min(); + var max = this.centroids.max(); var h = this.n * p; var bound = this.bound_mean_cumn(h); var lower = bound[0], upper = bound[1];