@jayesol/jayeson.lib.sports 2.2.5 → 2.2.6-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/codec.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- /// <reference types="long" />
2
1
  import * as proto from "./protobuf_bundle";
3
2
  import * as rec from "@jayesol/jayeson.lib.record";
4
3
  import { RuleCombination } from "@jayesol/jayeson.model";
4
+ import Long = require("long");
5
5
  export declare enum EncodeAction {
6
6
  INSERT = 0,
7
7
  UPDATE = 1,
@@ -21,7 +21,7 @@ export declare class CodecHelper {
21
21
  export declare class FilterRequest {
22
22
  private _requestId;
23
23
  private _ruleCombination;
24
- static readonly IGNORED_REQUEST_ID: number;
24
+ static readonly IGNORED_REQUEST_ID = -1;
25
25
  constructor(_requestId: number, _ruleCombination: RuleCombination);
26
26
  getRequestId(): number;
27
27
  getFilterData(): RuleCombination;
package/lib/codec.js CHANGED
@@ -1 +1,129 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var EncodeAction,mutable_1=require("./mutable");!function(t){t[t.INSERT=0]="INSERT",t[t.UPDATE=1]="UPDATE",t[t.DELETE=2]="DELETE"}(EncodeAction=exports.EncodeAction||(exports.EncodeAction={}));var CodecHelper=function(){function t(){}return t.prototype.coerceInt64=function(t){return t.toNumber?t.toNumber():t},t.prototype.populatePKIntoMetaInfo=function(t,e){return t[mutable_1.Const.AGGREGATE_KEY]=e.toString(),t},t.prototype.formatRate=function(t){return Math.round(1e4*t)/1e4},t}();exports.CodecHelper=CodecHelper;var FilterRequest=function(){function t(t,e){this._requestId=t,this._ruleCombination=e}return t.prototype.getRequestId=function(){return this._requestId},t.prototype.getFilterData=function(){return this._ruleCombination},t.prototype.toJSON=function(){return{requestId:this.getRequestId(),namespace:this._ruleCombination.namespace,filterRules:this._ruleCombination.filterRules}},t.IGNORED_REQUEST_ID=-1,t}();exports.FilterRequest=FilterRequest;var Util=function(){function l(){}return l.addKey=function(t,e){if(-1!=e.search(l.SEPARATOR))throw new TypeError("Incoming String cannot contain Separator: "+l.SEPARATOR+" Incoming: "+e);return 0==t.length?e:-1===t.indexOf(e)?t+l.SEPARATOR+e:t},l.removeKey=function(t,e){var n=t.split(l.SEPARATOR),r=e.split(l.SEPARATOR);n.sort();for(var o=0,i=r;o<i.length;o++){var u=i[o],c=n.indexOf(u);if(!(c<0)&&(n.splice(c,1),0==n.length))return""}for(var a=n[0],s=1;s<n.length;s++)a=l.addKey(a,n[s]);return a},l.containsKey=function(t,e){if(null==t)return!1;if(-1!=e.search(l.SEPARATOR))throw new TypeError("Incoming String cannot contain Separator: "+l.SEPARATOR+" Incoming: "+e);return!(t.split(l.SEPARATOR).indexOf(e)<0)},l.SEPARATOR=",",l}();exports.Util=Util;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Util = exports.FilterRequest = exports.CodecHelper = exports.EncodeAction = void 0;
4
+ const mutable_1 = require("./mutable");
5
+ var EncodeAction;
6
+ (function (EncodeAction) {
7
+ EncodeAction[EncodeAction["INSERT"] = 0] = "INSERT";
8
+ EncodeAction[EncodeAction["UPDATE"] = 1] = "UPDATE";
9
+ EncodeAction[EncodeAction["DELETE"] = 2] = "DELETE";
10
+ })(EncodeAction = exports.EncodeAction || (exports.EncodeAction = {}));
11
+ class CodecHelper {
12
+ constructor() { }
13
+ coerceInt64(val) {
14
+ if (val.toNumber) {
15
+ return val.toNumber();
16
+ }
17
+ else {
18
+ return val;
19
+ }
20
+ }
21
+ populatePKIntoMetaInfo(meta, key) {
22
+ meta[mutable_1.Const.AGGREGATE_KEY] = key.toString();
23
+ return meta;
24
+ }
25
+ formatRate(num) {
26
+ //Round input to 4 decimal places
27
+ return Math.round(num * 10000) / 10000;
28
+ }
29
+ }
30
+ exports.CodecHelper = CodecHelper;
31
+ class FilterRequest {
32
+ constructor(_requestId, _ruleCombination) {
33
+ this._requestId = _requestId;
34
+ this._ruleCombination = _ruleCombination;
35
+ }
36
+ getRequestId() {
37
+ return this._requestId;
38
+ }
39
+ getFilterData() {
40
+ return this._ruleCombination;
41
+ }
42
+ toJSON() {
43
+ return { "requestId": this.getRequestId(), "namespace": this._ruleCombination.namespace, "filterRules": this._ruleCombination.filterRules };
44
+ }
45
+ }
46
+ exports.FilterRequest = FilterRequest;
47
+ FilterRequest.IGNORED_REQUEST_ID = -1;
48
+ class Util {
49
+ /**
50
+ * Utility to Store array of String values as single String Also see
51
+ * {@link #removeKey(String, String)}
52
+ *
53
+ * @param existing
54
+ * "IBC_LIVE,CROWN_LIVE"
55
+ * @param incoming
56
+ * "SBO_LIVE"
57
+ * @return "IBC_LIVE,CROWN_LIVE,SBO_LIVE"
58
+ *
59
+ */
60
+ static addKey(existing, incoming) {
61
+ if (incoming.search(Util.SEPARATOR) != -1) {
62
+ throw new TypeError("Incoming String cannot contain Separator: " + Util.SEPARATOR + " Incoming: " + incoming);
63
+ }
64
+ if (existing.length == 0) {
65
+ return incoming;
66
+ }
67
+ else {
68
+ if (existing.indexOf(incoming) === -1) {
69
+ return existing + Util.SEPARATOR + incoming;
70
+ }
71
+ else {
72
+ return existing;
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Utility to remove element from string values Stored as String Also see
78
+ * {@link #addKey(String, String)}
79
+ *
80
+ * @param existing
81
+ * "IBC_LIVE,CROWN_LIVE"
82
+ * @param incoming
83
+ * "IBC_LIVE"
84
+ * @return "CROWN_LIVE". return empty string if there are no more keys. Return
85
+ * existing string if incoming is not present in existing
86
+ */
87
+ static removeKey(existing, incoming) {
88
+ let split = existing.split(Util.SEPARATOR);
89
+ let incomingArr = incoming.split(Util.SEPARATOR);
90
+ split.sort();
91
+ for (let incoming of incomingArr) {
92
+ let index = split.indexOf(incoming);
93
+ // If not found return
94
+ if (index < 0) {
95
+ continue;
96
+ }
97
+ else {
98
+ split.splice(index, 1);
99
+ // Return empty string if removed is empty
100
+ if (split.length == 0) {
101
+ return "";
102
+ }
103
+ }
104
+ }
105
+ let finalStr = split[0];
106
+ for (let i = 1; i < split.length; i++) {
107
+ finalStr = Util.addKey(finalStr, split[i]);
108
+ }
109
+ return finalStr;
110
+ }
111
+ static containsKey(existing, incoming) {
112
+ if (existing == undefined) {
113
+ return false;
114
+ }
115
+ if (incoming.search(Util.SEPARATOR) != -1) {
116
+ throw new TypeError("Incoming String cannot contain Separator: " + Util.SEPARATOR + " Incoming: " + incoming);
117
+ }
118
+ let split = existing.split(Util.SEPARATOR);
119
+ let index = split.indexOf(incoming);
120
+ if (index < 0) {
121
+ return false;
122
+ }
123
+ else {
124
+ return true;
125
+ }
126
+ }
127
+ }
128
+ exports.Util = Util;
129
+ Util.SEPARATOR = ",";
package/lib/core.js CHANGED
@@ -1 +1,497 @@
1
- "use strict";var __extends=this&&this.__extends||function(){var n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])};return function(t,e){function r(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}}(),__decorate=this&&this.__decorate||function(t,e,r,n){var o,i=arguments.length,s=i<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,r,n);else for(var a=t.length-1;0<=a;a--)(o=t[a])&&(s=(i<3?o(s):3<i?o(e,r,s):o(e,r))||s);return 3<i&&s&&Object.defineProperty(e,r,s),s},__metadata=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)},__param=this&&this.__param||function(r,n){return function(t,e){n(t,e,r)}};Object.defineProperty(exports,"__esModule",{value:!0});var data_structure_1=require("./data_structure"),Collections=require("typescript-collections"),T=require("ts-promise");require("reflect-metadata");var injection_js_1=require("injection-js"),jayeson_lib_record_1=require("@jayesol/jayeson.lib.record"),message_class_1=require("./message_class"),mutable_1=require("./mutable"),merge_1=require("./merge"),data_structure_2=require("./data_structure");exports.FSREPO_IMPL=new injection_js_1.InjectionToken("FSRepoInstance");var AbstractFSRepo=function(){function t(){this._handlers=new Collections.Set}return t.prototype.handlers=function(){return this._handlers},t.prototype.appendSnapshot=function(t,e){throw new Error("appendSnapshot is not implemented")},t.prototype.getSnapshot=function(t){throw new Error("getSnapshot is not implemented")},t.prototype.registerSnapshotHandler=function(t){this.handlers().add(t)},t.prototype.deRegisterSnapshotHandler=function(t){this.handlers().remove(t)},t.prototype.getRegisteredHandlers=function(){return this.handlers().toArray()},t.prototype.push=function(t){throw new Error("push is not implemented")},t.prototype.isReady=function(t){return null},t=__decorate([injection_js_1.Injectable(),__metadata("design:paramtypes",[])],t)}(),FSRepoImpl=function(o){function t(t,e){var r=o.call(this)||this;r.outputStreamName=t,r.sportsGroup=e,r._head=null;var n=r;return r.fssEndReceived=new T.Promise(function(t,e){n.promiseResolver=t,n.promiseRejector=e}),r}var e;return __extends(t,o),(e=t).prototype.head=function(){return this._head},t.prototype.appendSnapshot=function(t,e){return null==this._head?this.result=e.apply(null):this.result=e.apply(this._head),this._head=this.result.getAfter(),this.result.getDeltaOut()},t.prototype.getSnapshot=function(t){return void 0===t&&(t=""),null==this._head?data_structure_1.IndexedSnapshotImpl.EMPTY_SNAPSHOT:this._head},t.prototype.getTtlRemoveSnapshot=function(){return null==this._head?[]:[new TTLRemoveCheck(null,this._head.getPartitions().toArray(),this.outputStreamName)]},t.prototype.push=function(e){if(e.msgType()==this.sportsGroup.FULLSNAPSHOT_START());else if(e.msgType()==this.sportsGroup.FULLSNAPSHOT_END())this.promiseResolver(!0);else{var r=this;this._handlers.forEach(function(t){t.process(r.outputStreamName,e)})}},t.prototype.isReady=function(t){return this.fssEndReceived},t.outputStream=new injection_js_1.InjectionToken("aggregatedStreamName"),t=e=__decorate([injection_js_1.Injectable(),__param(0,injection_js_1.Inject(e.outputStream)),__metadata("design:paramtypes",[String,message_class_1.SportsFeedMessageGroup])],t)}(exports.AbstractFSRepo=AbstractFSRepo);exports.FSRepoImpl=FSRepoImpl;var Delta=function(){function t(t,e,r){this._incoming=t,this._after=e,this._before=r}return t.prototype.incoming=function(){return this._incoming},t.prototype.msgType=function(){return this._incoming.msgType()},t.prototype.after=function(){return this._after},t.prototype.delta=function(){return this._incoming.data()},t.prototype.before=function(){return this._before},t}();exports.Delta=Delta;var TTLType,TTLConfig=function(){function t(){this.livettl=18e4,this.todayttl=18e4,this.earlyttl=18e4,this.enableTtl=!0}return t.prototype.getLivettl=function(){return this.livettl},t.prototype.setLivettl=function(t){this.livettl=t},t.prototype.getTodayttl=function(){return this.todayttl},t.prototype.setTodayttl=function(t){this.todayttl=t},t.prototype.getEarlyttl=function(){return this.earlyttl},t.prototype.setEarlyttl=function(t){this.earlyttl=t},t.prototype.getRunInterval=function(){if(!this.enableTtl)return-1;var t=this.getLivettl(),e=this.getTodayttl(),r=this.getEarlyttl(),n=Math.min(t,e,r)/2;return n<1e3?1e4:n},t.prototype.isEnableTtl=function(){return this.enableTtl},t.prototype.setEnableTtl=function(t){this.enableTtl=t},t=__decorate([injection_js_1.Injectable()],t)}();exports.TTLConfig=TTLConfig,function(t){t[t.REMOVE=0]="REMOVE",t[t.RESTORE=1]="RESTORE"}(TTLType=exports.TTLType||(exports.TTLType={}));var TTLOutgoing=function(i){function t(t,e,r,n){var o=i.call(this,e,r,n)||this;return o.ttlType=t,o}return __extends(t,i),t.prototype.getTtlType=function(){return this.ttlType},t}(Delta);exports.TTLOutgoing=TTLOutgoing;var TTLCheck=function(){function t(t,e,r,n){this.ttlType=t,this.recycleBin=e,this.keys=r,this.stream=n}return t.prototype.getKeys=function(){return this.keys},t.prototype.getKeysMapping=function(){var e=new Collections.Dictionary;return this.keys.forEach(function(t){e.setValue(t,(new Date).getTime())}),e},t.prototype.getTtlType=function(){return this.ttlType},t.prototype.getRecycleBin=function(){return this.recycleBin},t.prototype.setRecycleBin=function(t){this.recycleBin=t},t.prototype.getStream=function(){return this.stream},t}(),TTLRestoreCheck=function(n){function t(t,e,r){return n.call(this,TTLType.RESTORE,t,e,r)||this}return __extends(t,n),t.prototype.apply=function(t){var n=this,o=t,i=!1,s=new Collections.Dictionary,a={},p=[];this.getKeys().forEach(function(t,e){if(n.getRecycleBin().containData(t)){i=!0;var r=(new Date).getTime();s.setValue(t,r),a=n.getRecycleBin().copyData(t,a),n.ttlRestoreWrapper=n.getRecycleBin().restoreData(new data_structure_2.TTLWrapper,o,t,r),o=n.ttlRestoreWrapper.getRemainingSs(),p.push(n.ttlRestoreWrapper.getRestoredSs())}});var e=[],r=new data_structure_2.MergeableWrapper;if(r.setAfter(o),i)return console.log("restore -----\x3e"+JSON.stringify(s.keys())),merge_1.DeltaTransformingLogicImpl.transformTTLRestore(p,this.getRecycleBin().getGrp(),this.getStream(),t,o,a,s);var c=new data_structure_1.Incoming(this.getRecycleBin().getGrp().ADMIN_REFRESH(),this.getStream(),new data_structure_1.IndexedSnapshotImpl(a,this.getKeysMapping()));return e.push(new TTLOutgoing(this.getTtlType(),c,o,t)),r.setDeltaOut(e),r},t}(exports.TTLCheck=TTLCheck);exports.TTLRestoreCheck=TTLRestoreCheck;var TTLRemoveCheck=function(n){function t(t,e,r){return n.call(this,TTLType.REMOVE,t,e,r)||this}return __extends(t,n),t.prototype.apply=function(t){for(var e=t.getPartitionMap(),r=new Collections.Dictionary,n=t,o=[],i=this.getRecycleBin().getTtlConfig(),s=!1,a=0,p=this.getKeys();a<p.length;a++){var c=p[a],u=0;if(e.containsKey(c)){switch(c.oddType()){case jayeson_lib_record_1.OddType.LIVE:u=e.getValue(c)+i.getLivettl();break;case jayeson_lib_record_1.OddType.TODAY:u=e.getValue(c)+i.getTodayttl();break;case jayeson_lib_record_1.OddType.EARLY:u=e.getValue(c)+i.getEarlyttl()}u<(new Date).getTime()&&(s=!0,r.setValue(c,e.getValue(c)),this.ttlRemoveWrapper=this.getRecycleBin().removeData(new data_structure_2.TTLWrapper,n,c),n=this.ttlRemoveWrapper.getRemainingSs(),o.push(this.ttlRemoveWrapper.getRemovedSs()))}}var l=[];if(s)return console.log("reseting -----\x3e"+JSON.stringify(r.keys())),merge_1.DeltaTransformingLogicImpl.transformTTLRemove(o,this.getRecycleBin().getGrp(),this.getStream(),t,n,r);var h=new data_structure_2.MergeableWrapper,g=new data_structure_1.Incoming(this.getRecycleBin().getGrp().ADMIN_REFRESH(),this.getStream(),new data_structure_1.IndexedSnapshotImpl({},this.getKeysMapping()));return l.push(new TTLOutgoing(this.getTtlType(),g,n,t)),h.setDeltaOut(l),h.setAfter(n),h},t}(TTLCheck);exports.TTLRemoveCheck=TTLRemoveCheck;var RecycleBin=function(){function t(t,e,r){this.ttlConfig=t,this.grp=e,this.fsRepo=r,this.expiredMatches=new Collections.Dictionary,this.ttlStatus=new Collections.Set}return t.prototype.removeData=function(t,e,r){if(!e.getPartitions().contains(r))return t.setRemainingSs(e),t.setRemovedSs(null),t;var n=mutable_1.BuilderProvider.getSnapshotBuilder(e),o=n.reset(r).build(),i=n.build();return this.expiredMatches.setValue(r,o),t.setRemovedSs(o),t.setRemainingSs(i),t},t.prototype.restoreData=function(t,e,r,n){var o=this.expiredMatches.getValue(r);if(null==o)return t.setRemainingSs(e),t.setRestoredSs(null),t;(new Collections.Dictionary).setValue(r,n);var i=mutable_1.BuilderProvider.getSnapshotBuilder(o);return i.markPartitionAsUpdated(r,n),o=i.build(),e=merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_MATCH(),o,e).getAfterSs(),e=merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_EVENT(),o,e).getAfterSs(),e=merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_ODD(),o,e).getAfterSs(),t.setRestoredSs(o),t.setRemainingSs(e),this.expiredMatches.remove(r),t},t.prototype.clearBin=function(t){this.expiredMatches.remove(t),this.ttlStatus.remove(t)},t.prototype.containData=function(t){return this.expiredMatches.containsKey(t)},t.prototype.getTtlConfig=function(){return this.ttlConfig},t.prototype.getFsRepo=function(){return this.fsRepo},t.prototype.getTtlRestoreSnapshot=function(n){var o=this,i=null;return this.ttlStatus.isEmpty()||(this.getGrp().DATA_RESET().id()==n.msgType().id()?n.data().getPartitions().forEach(function(t){console.log("Dropping partition "+t),o.expiredMatches.remove(t)}):n.data().getPartitionMap().forEach(function(t,e){var r=[];o.ttlStatus.contains(t)&&(o.ttlStatus.remove(t),r.push(t)),0<r.length&&(i=new TTLRestoreCheck(o,r,n.stream()))})),i},t.prototype.getTtlRemoveSnapshot=function(){var e=this,t=this.getFsRepo().getTtlRemoveSnapshot();return t.forEach(function(t){t.setRecycleBin(e),t.getKeys().forEach(function(t){e.ttlStatus.add(t)})}),t},t.prototype.copyData=function(t,e){var r=this.expiredMatches.getValue(t);if(void 0===r)return e;var n=new data_structure_1.IndexedSnapshotImpl(e);return n=merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_MATCH(),r,n).getAfterSs(),n=merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_EVENT(),r,n).getAfterSs(),(n=merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_ODD(),r,n).getAfterSs()).matchesSport},t.prototype.getGrp=function(){return this.grp},t=__decorate([injection_js_1.Injectable(),__metadata("design:paramtypes",[TTLConfig,message_class_1.SportsFeedMessageGroup,AbstractFSRepo])],t)}();exports.RecycleBin=RecycleBin;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
31
+ var __metadata = (this && this.__metadata) || function (k, v) {
32
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
33
+ };
34
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
35
+ return function (target, key) { decorator(target, key, paramIndex); }
36
+ };
37
+ var FSRepoImpl_1;
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.RecycleBin = exports.TTLRemoveCheck = exports.TTLRestoreCheck = exports.TTLCheck = exports.TTLOutgoing = exports.TTLType = exports.TTLConfig = exports.Delta = exports.FSRepoImpl = exports.AbstractFSRepo = exports.FSREPO_IMPL = void 0;
40
+ const data_structure_1 = require("./data_structure");
41
+ const Collections = __importStar(require("typescript-collections"));
42
+ const T = __importStar(require("ts-promise"));
43
+ //imports required for dependency injection
44
+ require("reflect-metadata");
45
+ const injection_js_1 = require("injection-js");
46
+ const jayeson_lib_record_1 = require("@jayesol/jayeson.lib.record");
47
+ const message_class_1 = require("./message_class");
48
+ const mutable_1 = require("./mutable");
49
+ const merge_1 = require("./merge");
50
+ const data_structure_2 = require("./data_structure");
51
+ exports.FSREPO_IMPL = new injection_js_1.InjectionToken('FSRepoInstance');
52
+ let AbstractFSRepo = class AbstractFSRepo {
53
+ constructor() {
54
+ this._handlers = new Collections.Set();
55
+ }
56
+ handlers() {
57
+ return this._handlers;
58
+ }
59
+ appendSnapshot(stream, mergeable) {
60
+ throw new Error("appendSnapshot is not implemented");
61
+ }
62
+ getSnapshot(streamName) {
63
+ throw new Error("getSnapshot is not implemented");
64
+ }
65
+ registerSnapshotHandler(ssHandler) {
66
+ this.handlers().add(ssHandler);
67
+ }
68
+ deRegisterSnapshotHandler(ssHandler) {
69
+ this.handlers().remove(ssHandler);
70
+ }
71
+ getRegisteredHandlers() {
72
+ return this.handlers().toArray();
73
+ }
74
+ push(outgoing) {
75
+ throw new Error("push is not implemented");
76
+ }
77
+ isReady(stream) {
78
+ return null;
79
+ }
80
+ };
81
+ AbstractFSRepo = __decorate([
82
+ (0, injection_js_1.Injectable)(),
83
+ __metadata("design:paramtypes", [])
84
+ ], AbstractFSRepo);
85
+ exports.AbstractFSRepo = AbstractFSRepo;
86
+ let FSRepoImpl = FSRepoImpl_1 = class FSRepoImpl extends AbstractFSRepo {
87
+ constructor(outputStreamName, sportsGroup) {
88
+ super();
89
+ this.outputStreamName = outputStreamName;
90
+ this.sportsGroup = sportsGroup;
91
+ this._head = null;
92
+ let instance = this;
93
+ this.fssEndReceived = new T.Promise((resolve, reject) => {
94
+ instance.promiseResolver = resolve;
95
+ instance.promiseRejector = reject;
96
+ });
97
+ }
98
+ head() {
99
+ return this._head;
100
+ }
101
+ appendSnapshot(stream, logic) {
102
+ //single threaded, locking is unnecessary.
103
+ if (this._head == null) {
104
+ this.result = logic.apply(null);
105
+ this._head = this.result.getAfter();
106
+ }
107
+ else {
108
+ this.result = logic.apply(this._head);
109
+ this._head = this.result.getAfter();
110
+ }
111
+ return this.result.getDeltaOut();
112
+ }
113
+ getSnapshot(streamName = "") {
114
+ if (this._head == null) {
115
+ return data_structure_1.IndexedSnapshotImpl.EMPTY_SNAPSHOT;
116
+ }
117
+ return this._head;
118
+ }
119
+ getTtlRemoveSnapshot() {
120
+ if (this._head == null) {
121
+ return [];
122
+ }
123
+ let ttlRemoveCheck = new TTLRemoveCheck(null, this._head.getPartitions().toArray(), this.outputStreamName);
124
+ return [ttlRemoveCheck];
125
+ }
126
+ push(outgoing) {
127
+ if (outgoing.msgType() == this.sportsGroup.FULLSNAPSHOT_START()) {
128
+ //ignore this
129
+ }
130
+ else if (outgoing.msgType() == this.sportsGroup.FULLSNAPSHOT_END()) {
131
+ this.promiseResolver(true);
132
+ }
133
+ else {
134
+ let _instance = this;
135
+ this._handlers.forEach(function (handler) {
136
+ handler.process(_instance.outputStreamName, outgoing);
137
+ });
138
+ }
139
+ }
140
+ isReady(stream) {
141
+ return this.fssEndReceived;
142
+ }
143
+ };
144
+ FSRepoImpl.outputStream = new injection_js_1.InjectionToken('aggregatedStreamName');
145
+ FSRepoImpl = FSRepoImpl_1 = __decorate([
146
+ (0, injection_js_1.Injectable)(),
147
+ __param(0, (0, injection_js_1.Inject)(FSRepoImpl_1.outputStream)),
148
+ __metadata("design:paramtypes", [String, message_class_1.SportsFeedMessageGroup])
149
+ ], FSRepoImpl);
150
+ exports.FSRepoImpl = FSRepoImpl;
151
+ class Delta {
152
+ constructor(_incoming, _after, _before) {
153
+ this._incoming = _incoming;
154
+ this._after = _after;
155
+ this._before = _before;
156
+ }
157
+ incoming() {
158
+ return this._incoming;
159
+ }
160
+ msgType() {
161
+ return this._incoming.msgType();
162
+ }
163
+ after() {
164
+ return this._after;
165
+ }
166
+ delta() {
167
+ return this._incoming.data();
168
+ }
169
+ before() {
170
+ return this._before;
171
+ }
172
+ }
173
+ exports.Delta = Delta;
174
+ let TTLConfig = class TTLConfig {
175
+ constructor() {
176
+ this.livettl = 180000;
177
+ this.todayttl = 180000;
178
+ this.earlyttl = 180000;
179
+ // Boolean to see if ttl is enabled or not.
180
+ // If set to false,ttl will be disabled even though ttl values are set
181
+ this.enableTtl = true;
182
+ }
183
+ getLivettl() {
184
+ return this.livettl;
185
+ }
186
+ setLivettl(livettl) {
187
+ this.livettl = livettl;
188
+ }
189
+ getTodayttl() {
190
+ return this.todayttl;
191
+ }
192
+ setTodayttl(todayttl) {
193
+ this.todayttl = todayttl;
194
+ }
195
+ getEarlyttl() {
196
+ return this.earlyttl;
197
+ }
198
+ setEarlyttl(earlyttl) {
199
+ this.earlyttl = earlyttl;
200
+ }
201
+ getRunInterval() {
202
+ if (!this.enableTtl) {
203
+ return -1;
204
+ }
205
+ let liveTTL = this.getLivettl();
206
+ let todayTTL = this.getTodayttl();
207
+ let earlyTTL = this.getEarlyttl();
208
+ let sleepDuration = Math.min(liveTTL, todayTTL, earlyTTL) / 2;
209
+ return (sleepDuration < 1000) ? 10000 : sleepDuration;
210
+ }
211
+ isEnableTtl() {
212
+ return this.enableTtl;
213
+ }
214
+ setEnableTtl(enableTtl) {
215
+ this.enableTtl = enableTtl;
216
+ }
217
+ };
218
+ TTLConfig = __decorate([
219
+ (0, injection_js_1.Injectable)()
220
+ ], TTLConfig);
221
+ exports.TTLConfig = TTLConfig;
222
+ var TTLType;
223
+ (function (TTLType) {
224
+ TTLType[TTLType["REMOVE"] = 0] = "REMOVE";
225
+ TTLType[TTLType["RESTORE"] = 1] = "RESTORE";
226
+ })(TTLType = exports.TTLType || (exports.TTLType = {}));
227
+ class TTLOutgoing extends Delta {
228
+ constructor(ttlType, incoming, after, before) {
229
+ super(incoming, after, before);
230
+ this.ttlType = ttlType;
231
+ }
232
+ getTtlType() {
233
+ return this.ttlType;
234
+ }
235
+ }
236
+ exports.TTLOutgoing = TTLOutgoing;
237
+ class TTLCheck {
238
+ constructor(ttlType, recycleBin, keys, stream) {
239
+ this.ttlType = ttlType;
240
+ this.recycleBin = recycleBin;
241
+ this.keys = keys;
242
+ this.stream = stream;
243
+ }
244
+ getKeys() {
245
+ return this.keys;
246
+ }
247
+ getKeysMapping() {
248
+ let mapping = new Collections.Dictionary();
249
+ this.keys.forEach(key => {
250
+ mapping.setValue(key, new Date().getTime());
251
+ });
252
+ return mapping;
253
+ }
254
+ getTtlType() {
255
+ return this.ttlType;
256
+ }
257
+ getRecycleBin() {
258
+ return this.recycleBin;
259
+ }
260
+ setRecycleBin(recycleBin) {
261
+ this.recycleBin = recycleBin;
262
+ }
263
+ getStream() {
264
+ return this.stream;
265
+ }
266
+ }
267
+ exports.TTLCheck = TTLCheck;
268
+ class TTLRestoreCheck extends TTLCheck {
269
+ constructor(recycleBin, keys, stream) {
270
+ super(TTLType.RESTORE, recycleBin, keys, stream);
271
+ }
272
+ apply(before) {
273
+ let restoredSS = before;
274
+ let atLeastOneRestored = false;
275
+ let restoredKeys = new Collections.Dictionary();
276
+ let matches = {};
277
+ let ttlRestoredList = [];
278
+ //for each key in this object
279
+ this.getKeys().forEach((key, val) => {
280
+ //check if key is present in recycle bin
281
+ if (this.getRecycleBin().containData(key)) {
282
+ atLeastOneRestored = true;
283
+ let restoreTime = new Date().getTime();
284
+ restoredKeys.setValue(key, restoreTime);
285
+ matches = this.getRecycleBin().copyData(key, matches);
286
+ //if it is present, restore data
287
+ this.ttlRestoreWrapper = this.getRecycleBin().restoreData(new data_structure_2.TTLWrapper(), restoredSS, key, restoreTime);
288
+ restoredSS = this.ttlRestoreWrapper.getRemainingSs();
289
+ ttlRestoredList.push(this.ttlRestoreWrapper.getRestoredSs());
290
+ }
291
+ });
292
+ let ttlOut = [];
293
+ let wrap = new data_structure_2.MergeableWrapper();
294
+ wrap.setAfter(restoredSS);
295
+ if (atLeastOneRestored) {
296
+ console.log("restore ----->" + JSON.stringify(restoredKeys.keys()));
297
+ return merge_1.DeltaTransformingLogicImpl.transformTTLRestore(ttlRestoredList, this.getRecycleBin().getGrp(), this.getStream(), before, restoredSS, matches, restoredKeys);
298
+ }
299
+ else {
300
+ //mark as refresh if not a snapshot message
301
+ let incoming = new data_structure_1.Incoming(this.getRecycleBin().getGrp().ADMIN_REFRESH(), this.getStream(), new data_structure_1.IndexedSnapshotImpl(matches, this.getKeysMapping()));
302
+ ttlOut.push(new TTLOutgoing(this.getTtlType(), incoming, restoredSS, before));
303
+ wrap.setDeltaOut(ttlOut);
304
+ return wrap;
305
+ }
306
+ }
307
+ }
308
+ exports.TTLRestoreCheck = TTLRestoreCheck;
309
+ class TTLRemoveCheck extends TTLCheck {
310
+ constructor(recycleBin, keys, stream) {
311
+ super(TTLType.REMOVE, recycleBin, keys, stream);
312
+ }
313
+ apply(before) {
314
+ let allKeys = before.getPartitionMap();
315
+ let keysRemoved = new Collections.Dictionary();
316
+ let removedSnapshot = before;
317
+ let ttlRemoveList = [];
318
+ let ttlConfig = this.getRecycleBin().getTtlConfig();
319
+ let atLeastOneKeyRemoved = false;
320
+ for (let key of this.getKeys()) {
321
+ let threshold = 0;
322
+ if (!allKeys.containsKey(key)) {
323
+ continue;
324
+ }
325
+ switch (key.oddType()) {
326
+ case jayeson_lib_record_1.OddType.LIVE:
327
+ threshold = allKeys.getValue(key) + ttlConfig.getLivettl();
328
+ break;
329
+ case jayeson_lib_record_1.OddType.TODAY:
330
+ threshold = allKeys.getValue(key) + ttlConfig.getTodayttl();
331
+ break;
332
+ case jayeson_lib_record_1.OddType.EARLY:
333
+ threshold = allKeys.getValue(key) + ttlConfig.getEarlyttl();
334
+ break;
335
+ }
336
+ if (threshold < new Date().getTime()) {
337
+ //remove expired odds
338
+ atLeastOneKeyRemoved = true;
339
+ keysRemoved.setValue(key, allKeys.getValue(key));
340
+ this.ttlRemoveWrapper = this.getRecycleBin().removeData(new data_structure_2.TTLWrapper(), removedSnapshot, key);
341
+ removedSnapshot = this.ttlRemoveWrapper.getRemainingSs();
342
+ ttlRemoveList.push(this.ttlRemoveWrapper.getRemovedSs());
343
+ }
344
+ }
345
+ let ttlOut = [];
346
+ if (atLeastOneKeyRemoved) {
347
+ console.log("reseting ----->" + JSON.stringify(keysRemoved.keys()));
348
+ return merge_1.DeltaTransformingLogicImpl.transformTTLRemove(ttlRemoveList, this.getRecycleBin().getGrp(), this.getStream(), before, removedSnapshot, keysRemoved);
349
+ }
350
+ else {
351
+ let wrapper = new data_structure_2.MergeableWrapper();
352
+ let incoming = new data_structure_1.Incoming(this.getRecycleBin().getGrp().ADMIN_REFRESH(), this.getStream(), new data_structure_1.IndexedSnapshotImpl({}, this.getKeysMapping()));
353
+ ttlOut.push(new TTLOutgoing(this.getTtlType(), incoming, removedSnapshot, before));
354
+ wrapper.setDeltaOut(ttlOut);
355
+ wrapper.setAfter(removedSnapshot);
356
+ return wrapper;
357
+ }
358
+ }
359
+ }
360
+ exports.TTLRemoveCheck = TTLRemoveCheck;
361
+ let RecycleBin = class RecycleBin {
362
+ constructor(ttlConfig, grp, fsRepo) {
363
+ this.ttlConfig = ttlConfig;
364
+ this.grp = grp;
365
+ this.fsRepo = fsRepo;
366
+ this.expiredMatches = new Collections.Dictionary();
367
+ this.ttlStatus = new Collections.Set();
368
+ }
369
+ /**
370
+ * Remove the data for a given PartitionKey from a snapshot and return the
371
+ * modified snapshot. The removed data will be stored in this recycle bin.
372
+ *
373
+ * @param snapshot
374
+ * @param key
375
+ */
376
+ removeData(ttlRemoveWrapper, snapshot, key) {
377
+ if (!snapshot.getPartitions().contains(key)) {
378
+ ttlRemoveWrapper.setRemainingSs(snapshot);
379
+ ttlRemoveWrapper.setRemovedSs(null);
380
+ return ttlRemoveWrapper;
381
+ }
382
+ let sBuilder = mutable_1.BuilderProvider.getSnapshotBuilder(snapshot);
383
+ // remove the data with given PartitionKey from sBuilder
384
+ // and get a snapshot containing only the removed data.
385
+ let removedData = sBuilder.reset(key).build();
386
+ //save the data to be removed
387
+ let result = sBuilder.build();
388
+ this.expiredMatches.setValue(key, removedData);
389
+ ttlRemoveWrapper.setRemovedSs(removedData);
390
+ ttlRemoveWrapper.setRemainingSs(result);
391
+ // return the snapshot with PartitionKey data removed
392
+ return ttlRemoveWrapper;
393
+ }
394
+ /**
395
+ * Retrieves the data in this bin with given PartitionKey and combine it with
396
+ * the given snapshot.
397
+ *
398
+ * @param parent
399
+ * @param key
400
+ */
401
+ restoreData(ttlRestore, parent, key, restoreTime) {
402
+ let partition = this.expiredMatches.getValue(key);
403
+ // Return if expired data doesn't contain given key
404
+ if (partition == null) {
405
+ ttlRestore.setRemainingSs(parent);
406
+ ttlRestore.setRestoredSs(null);
407
+ return ttlRestore;
408
+ }
409
+ //update restored partition's refresh time with the restore time
410
+ let updateTime = new Collections.Dictionary();
411
+ updateTime.setValue(key, restoreTime);
412
+ let sBuilder = mutable_1.BuilderProvider.getSnapshotBuilder(partition);
413
+ sBuilder.markPartitionAsUpdated(key, restoreTime);
414
+ partition = sBuilder.build();
415
+ parent = merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_MATCH(), partition, parent).getAfterSs();
416
+ parent = merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_EVENT(), partition, parent).getAfterSs();
417
+ parent = merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_ODD(), partition, parent).getAfterSs();
418
+ ttlRestore.setRestoredSs(partition);
419
+ ttlRestore.setRemainingSs(parent);
420
+ this.expiredMatches.remove(key);
421
+ return ttlRestore;
422
+ }
423
+ clearBin(key) {
424
+ this.expiredMatches.remove(key);
425
+ this.ttlStatus.remove(key);
426
+ }
427
+ containData(key) {
428
+ return this.expiredMatches.containsKey(key);
429
+ }
430
+ getTtlConfig() {
431
+ return this.ttlConfig;
432
+ }
433
+ getFsRepo() {
434
+ return this.fsRepo;
435
+ }
436
+ getTtlRestoreSnapshot(incoming) {
437
+ let restoreSnapshot = null;
438
+ if (this.ttlStatus.isEmpty()) {
439
+ return restoreSnapshot;
440
+ }
441
+ if (this.getGrp().DATA_RESET().id() == incoming.msgType().id()) {
442
+ incoming.data().getPartitions().forEach(pKey => {
443
+ console.log("Dropping partition " + pKey);
444
+ this.expiredMatches.remove(pKey);
445
+ });
446
+ }
447
+ else {
448
+ incoming.data().getPartitionMap().forEach((pKey, val) => {
449
+ let restoreKeys = [];
450
+ if (this.ttlStatus.contains(pKey)) {
451
+ this.ttlStatus.remove(pKey);
452
+ restoreKeys.push(pKey);
453
+ }
454
+ if (restoreKeys.length > 0) {
455
+ restoreSnapshot = new TTLRestoreCheck(this, restoreKeys, incoming.stream());
456
+ }
457
+ });
458
+ }
459
+ return restoreSnapshot;
460
+ }
461
+ getTtlRemoveSnapshot() {
462
+ let ttlSnapshots = this.getFsRepo().getTtlRemoveSnapshot();
463
+ ttlSnapshots.forEach(removeSnapshot => {
464
+ removeSnapshot.setRecycleBin(this);
465
+ removeSnapshot.getKeys().forEach(partitionKey => {
466
+ this.ttlStatus.add(partitionKey);
467
+ });
468
+ });
469
+ return ttlSnapshots;
470
+ }
471
+ /**
472
+ * Copies the data in this RecycleBin related to the given PartitionKey into the
473
+ * list of matches.
474
+ *
475
+ * @param key
476
+ * @param matches
477
+ */
478
+ copyData(key, matches) {
479
+ let snapshot = this.expiredMatches.getValue(key);
480
+ if (snapshot === undefined) {
481
+ return matches;
482
+ }
483
+ let parent = new data_structure_1.IndexedSnapshotImpl(matches);
484
+ parent = merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_MATCH(), snapshot, parent).getAfterSs();
485
+ parent = merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_EVENT(), snapshot, parent).getAfterSs();
486
+ parent = merge_1.SnapshotUtil.combineSnapshots(this.getGrp().DATA_INSERT_ODD(), snapshot, parent).getAfterSs();
487
+ return parent.matchesSport;
488
+ }
489
+ getGrp() {
490
+ return this.grp;
491
+ }
492
+ };
493
+ RecycleBin = __decorate([
494
+ (0, injection_js_1.Injectable)(),
495
+ __metadata("design:paramtypes", [TTLConfig, message_class_1.SportsFeedMessageGroup, AbstractFSRepo])
496
+ ], RecycleBin);
497
+ exports.RecycleBin = RecycleBin;