From 5cf16d01b517b1ca5078420fd31d29dce14fc587 Mon Sep 17 00:00:00 2001 From: Jordi Bunster Date: Tue, 27 Apr 2021 08:14:21 -0700 Subject: [PATCH] use ES6 Map if we can (#602) --- .eslintignore | 4 - src/Common/ArrayHashMap.ts | 71 ++---------- src/Common/HashMap.test.ts | 70 ------------ src/Common/HashMap.ts | 45 -------- src/Common/ObjectCache.test.ts | 2 +- src/Common/ObjectCache.ts | 59 +++------- .../SettingsComponent.test.tsx.snap | 104 ++++-------------- .../GraphExplorerComponent/D3ForceGraph.ts | 11 +- .../GraphExplorerComponent/EdgeInfoCache.ts | 11 +- .../GremlinClient.test.ts | 10 +- .../GraphExplorerComponent/GremlinClient.ts | 9 +- .../Panes/CassandraAddCollectionPane.ts | 5 +- .../__snapshots__/SettingsPane.test.tsx.snap | 52 ++------- .../StringInputPane.test.tsx.snap | 52 ++------- .../UploadItemsPane.test.tsx.snap | 26 +---- ...eteDatabaseConfirmationPanel.test.tsx.snap | 26 +---- src/Explorer/Tabs/MongoShellTab.ts | 5 +- src/Explorer/Tabs/QueryTab.ts | 17 ++- src/Explorer/Tree/ResourceTreeAdapter.tsx | 4 +- tsconfig.strict.json | 1 - 20 files changed, 106 insertions(+), 478 deletions(-) delete mode 100644 src/Common/HashMap.test.ts delete mode 100644 src/Common/HashMap.ts diff --git a/.eslintignore b/.eslintignore index af7128111..2e9564de7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -5,7 +5,6 @@ src/Api/Apis.ts src/AuthType.ts src/Bindings/BindingHandlersRegisterer.ts src/Bindings/ReactBindingHandler.ts -src/Common/ArrayHashMap.ts src/Common/Constants.ts src/Common/CosmosClient.test.ts src/Common/CosmosClient.ts @@ -13,15 +12,12 @@ src/Common/DataAccessUtilityBase.test.ts src/Common/DataAccessUtilityBase.ts src/Common/EditableUtility.ts src/Common/HashMap.test.ts -src/Common/HashMap.ts src/Common/Logger.test.ts src/Common/MessageHandler.test.ts src/Common/MessageHandler.ts src/Common/MongoProxyClient.test.ts src/Common/MongoUtility.ts src/Common/NotificationsClientBase.ts -src/Common/ObjectCache.test.ts -src/Common/ObjectCache.ts src/Common/QueriesClient.ts src/Common/Splitter.ts src/Config.ts diff --git a/src/Common/ArrayHashMap.ts b/src/Common/ArrayHashMap.ts index eef791373..8b1600d6c 100644 --- a/src/Common/ArrayHashMap.ts +++ b/src/Common/ArrayHashMap.ts @@ -1,49 +1,9 @@ -import { HashMap } from "./HashMap"; - /** * Hash map of arrays which allows to: * - push an item by key: add to array and create array if needed * - remove item by key: remove from array and delete array if needed */ - -export class ArrayHashMap { - private store: HashMap; - - constructor() { - this.store = new HashMap(); - } - - public has(key: string): boolean { - return this.store.has(key); - } - - public get(key: string): T[] { - return this.store.get(key); - } - - public size(): number { - return this.store.size(); - } - - public clear(): void { - this.store.clear(); - } - - public keys(): string[] { - return this.store.keys(); - } - - public delete(key: string): boolean { - return this.store.delete(key); - } - - public forEach(key: string, iteratorFct: (value: T) => void) { - const values = this.store.get(key); - if (values) { - values.forEach((value) => iteratorFct(value)); - } - } - +export class ArrayHashMap extends Map { /** * Insert item into array. * If no array, create one. @@ -52,16 +12,8 @@ export class ArrayHashMap { * @param item */ public push(key: string, item: T): void { - let itemsArray: T[] = this.store.get(key); - if (!itemsArray) { - itemsArray = [item]; - this.store.set(key, itemsArray); - return; - } - - if (itemsArray.indexOf(item) === -1) { - itemsArray.push(item); - } + const array = this.get(key); + array ? array.includes(item) || array.push(item) : this.set(key, [item]); } /** @@ -70,18 +22,11 @@ export class ArrayHashMap { * @param key * @param itemToRemove */ - public remove(key: string, itemToRemove: T) { - if (!this.store.has(key)) { - return; - } - - const itemsArray = this.store.get(key); - const index = itemsArray.indexOf(itemToRemove); - if (index >= 0) { - itemsArray.splice(index, 1); - if (itemsArray.length === 0) { - this.store.delete(key); - } + public remove(key: string, itemToRemove: T): void { + const array = this.get(key); + if (array) { + const remaining = array.filter((item) => item !== itemToRemove); + remaining.length ? this.set(key, remaining) : this.delete(key); } } } diff --git a/src/Common/HashMap.test.ts b/src/Common/HashMap.test.ts deleted file mode 100644 index b3bdaa225..000000000 --- a/src/Common/HashMap.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { HashMap } from "./HashMap"; - -describe("HashMap", () => { - it("should test if key/val exists", () => { - const map = new HashMap(); - map.set("a", 123); - - expect(map.has("a")).toBe(true); - expect(map.has("b")).toBe(false); - }); - - it("should get object back", () => { - const map = new HashMap(); - map.set("a", "123"); - map.set("a", "456"); - - expect(map.get("a")).toBe("456"); - expect(map.get("a")).not.toBe("123"); - }); - - it("should return the right size", () => { - const map = new HashMap(); - map.set("a", "123"); - map.set("b", "456"); - - expect(map.size()).toBe(2); - }); - - it("should be iterable", () => { - const map = new HashMap(); - map.set("a", 1); - map.set("b", 10); - map.set("c", 100); - map.set("d", 1000); - - let i = 0; - map.forEach((key: string, value: number) => { - i += value; - }); - expect(i).toBe(1111); - }); - - it("should be deleted", () => { - const map = new HashMap(); - map.set("a", 1); - map.set("b", 10); - - expect(map.delete("a")).toBe(true); - expect(map.delete("c")).toBe(false); - expect(map.has("a")).toBe(false); - expect(map.has("b")).toBe(true); - }); - - it("should clear", () => { - const map = new HashMap(); - map.set("a", 1); - map.clear(); - expect(map.size()).toBe(0); - expect(map.has("a")).toBe(false); - }); - - it("should return all keys", () => { - const map = new HashMap(); - map.set("a", 1); - map.set("b", 1); - expect(map.keys()).toEqual(["a", "b"]); - map.clear(); - expect(map.keys().length).toBe(0); - }); -}); diff --git a/src/Common/HashMap.ts b/src/Common/HashMap.ts deleted file mode 100644 index 0a55b08c5..000000000 --- a/src/Common/HashMap.ts +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Simple hashmap implementation that doesn't rely on ES6 Map nor polyfills - */ -export class HashMap { - constructor(private container: { [key: string]: T } = {}) {} - - public has(key: string): boolean { - return this.container.hasOwnProperty(key); - } - - public set(key: string, value: T): void { - this.container[key] = value; - } - - public get(key: string): T { - return this.container[key]; - } - - public size(): number { - return Object.keys(this.container).length; - } - - public delete(key: string): boolean { - if (this.has(key)) { - delete this.container[key]; - return true; - } - - return false; - } - - public clear(): void { - this.container = {}; - } - - public keys(): string[] { - return Object.keys(this.container); - } - - public forEach(iteratorFct: (key: string, value: T) => void) { - for (const k in this.container) { - iteratorFct(k, this.container[k]); - } - } -} diff --git a/src/Common/ObjectCache.test.ts b/src/Common/ObjectCache.test.ts index 3a9f8f17a..7f6b5f7a7 100644 --- a/src/Common/ObjectCache.test.ts +++ b/src/Common/ObjectCache.test.ts @@ -7,7 +7,7 @@ describe("Object cache", () => { cache.set("b", 2); cache.set("c", 3); cache.set("d", 4); - expect(cache.size()).toBe(2); + expect(cache.size).toBe(2); }); it("should remove first added element to keep size at limit", () => { diff --git a/src/Common/ObjectCache.ts b/src/Common/ObjectCache.ts index 9149aba9b..0c6326087 100644 --- a/src/Common/ObjectCache.ts +++ b/src/Common/ObjectCache.ts @@ -1,56 +1,27 @@ -import { HashMap } from "./HashMap"; - -export class ObjectCache extends HashMap { - private keyQueue: string[]; // Last touched key FIFO to purge cache if too big. - private maxNbElements: number; - - public constructor(maxNbElements: number) { +export class ObjectCache extends Map { + constructor(private limit: number) { super(); - this.keyQueue = []; - this.maxNbElements = maxNbElements; - this.clear(); } - public clear(): void { - super.clear(); - this.keyQueue = []; + public get(key: string): T | undefined { + return this.touch(key); } - public get(key: string): T { - this.markKeyAsTouched(key); - return super.get(key); - } - - public set(key: string, value: T): void { - super.set(key, value); - - this.markKeyAsTouched(key); - - if (super.size() > this.maxNbElements && key !== this.keyQueue[0]) { - this.reduceCacheSize(); + public set(key: string, value: T): this { + if (this.size === this.limit) { + this.delete(this.keys().next().value); } + + return this.touch(key, value), this; } - /** - * Invalidate elements to keep the total number below the limit - */ - private reduceCacheSize(): void { - // remove a key - const oldKey = this.keyQueue.shift(); - if (oldKey) { - super.delete(oldKey); + private touch(key: string, value = super.get(key)) { + // Map keeps (re) insertion order according to ES6 spec + if (value) { + this.delete(key); + super.set(key, value); } - } - /** - * Bubble up this key as new. - * @param key - */ - private markKeyAsTouched(key: string) { - const n = this.keyQueue.indexOf(key); - if (n > -1) { - this.keyQueue.splice(n, 1); - } - this.keyQueue.push(key); + return value; } } diff --git a/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap b/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap index 81c72cf44..5018a7821 100644 --- a/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap +++ b/src/Explorer/Controls/Settings/__snapshots__/SettingsComponent.test.tsx.snap @@ -199,9 +199,7 @@ exports[`SettingsComponent renders 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -378,9 +376,7 @@ exports[`SettingsComponent renders 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -494,21 +490,9 @@ exports[`SettingsComponent renders 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { @@ -731,9 +715,7 @@ exports[`SettingsComponent renders 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -910,9 +892,7 @@ exports[`SettingsComponent renders 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -1026,21 +1006,9 @@ exports[`SettingsComponent renders 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { @@ -1276,9 +1244,7 @@ exports[`SettingsComponent renders 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -1455,9 +1421,7 @@ exports[`SettingsComponent renders 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -1571,21 +1535,9 @@ exports[`SettingsComponent renders 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { @@ -1808,9 +1760,7 @@ exports[`SettingsComponent renders 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -1987,9 +1937,7 @@ exports[`SettingsComponent renders 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -2103,21 +2051,9 @@ exports[`SettingsComponent renders 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { diff --git a/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts b/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts index 31a01f0a3..393e92b84 100644 --- a/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts +++ b/src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts @@ -11,7 +11,6 @@ import * as ko from "knockout"; import Q from "q"; import _ from "underscore"; import * as Constants from "../../../Common/Constants"; -import { HashMap } from "../../../Common/HashMap"; import { NeighborType } from "../../../Contracts/ViewModels"; import { logConsoleError } from "../../../Utils/NotificationConsoleUtils"; import { GraphConfig } from "../../Tabs/GraphTab"; @@ -195,8 +194,8 @@ export class D3ForceGraph implements GraphRenderer { * Count edges and store in a hashmap: vertex id <--> number of links * @param linkSelection */ - public static countEdges(links: D3Link[]): HashMap { - const countMap = new HashMap(); + public static countEdges(links: D3Link[]): Map { + const countMap = new Map(); links.forEach((l: D3Link) => { let val = countMap.get(l.inV) || 0; val += 1; @@ -407,7 +406,7 @@ export class D3ForceGraph implements GraphRenderer { const rootId = graph.findRootNodeId(); // Remember nodes current position - const posMap = new HashMap(); + const posMap = new Map(); this.simulation.nodes().forEach((d: D3Node) => { if (d.x == undefined || d.y == undefined) { return; @@ -501,8 +500,8 @@ export class D3ForceGraph implements GraphRenderer { if (!nodes || nodes.length === 0) { return; } - const nodeFinalPositionMap = new HashMap(); + const nodeFinalPositionMap = new Map(); const viewCenter = this.viewCenter; const nonFixedNodes = _.filter(nodes, (node: D3Node) => { return !node._isFixedPosition && node.x === viewCenter.x && node.y === viewCenter.y; @@ -559,7 +558,7 @@ export class D3ForceGraph implements GraphRenderer { newNodes.selectAll(".loadmore").attr("visibility", "hidden").transition().delay(600).attr("visibility", "visible"); } - private restartSimulation(graph: GraphData, posMap: HashMap) { + private restartSimulation(graph: GraphData, posMap: Map) { if (!graph) { return; } diff --git a/src/Explorer/Graph/GraphExplorerComponent/EdgeInfoCache.ts b/src/Explorer/Graph/GraphExplorerComponent/EdgeInfoCache.ts index 681682102..10e255eb9 100644 --- a/src/Explorer/Graph/GraphExplorerComponent/EdgeInfoCache.ts +++ b/src/Explorer/Graph/GraphExplorerComponent/EdgeInfoCache.ts @@ -1,5 +1,5 @@ import { ObjectCache } from "../../../Common/ObjectCache"; -import { GremlinVertex, GraphData } from "./GraphData"; +import { GraphData, GremlinVertex } from "./GraphData"; /** * Remember vertex edge information @@ -10,9 +10,8 @@ export class EdgeInfoCache extends ObjectCache { * @param vertex */ public addVertex(vertex: GremlinVertex): void { - let v: GremlinVertex; - if (super.has(vertex.id)) { - v = super.get(vertex.id); + let v = super.get(vertex.id); + if (super.has(vertex.id) && v) { GraphData.addEdgeInfoToVertex(v, vertex); v._outEdgeIds = vertex._outEdgeIds; v._inEdgeIds = vertex._inEdgeIds; @@ -29,8 +28,8 @@ export class EdgeInfoCache extends ObjectCache { * @param id */ public mergeEdgeInfo(target: GremlinVertex): void { - if (super.has(target.id)) { - const cachedVertex = super.get(target.id); + const cachedVertex = super.get(target.id); + if (super.has(target.id) && cachedVertex) { GraphData.addEdgeInfoToVertex(target, cachedVertex); target._outEdgeIds = cachedVertex._outEdgeIds; target._inEdgeIds = cachedVertex._inEdgeIds; diff --git a/src/Explorer/Graph/GraphExplorerComponent/GremlinClient.test.ts b/src/Explorer/Graph/GraphExplorerComponent/GremlinClient.test.ts index 86c918521..5f1619ab7 100644 --- a/src/Explorer/Graph/GraphExplorerComponent/GremlinClient.test.ts +++ b/src/Explorer/Graph/GraphExplorerComponent/GremlinClient.test.ts @@ -1,7 +1,7 @@ import * as sinon from "sinon"; -import { GremlinClient, GremlinClientParameters } from "./GremlinClient"; -import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils"; import * as Logger from "../../../Common/Logger"; +import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils"; +import { GremlinClient, GremlinClientParameters } from "./GremlinClient"; describe("Gremlin Client", () => { const emptyParams: GremlinClientParameters = { @@ -70,7 +70,7 @@ describe("Gremlin Client", () => { gremlinClient.execute("fake query"); gremlinClient.execute("fake query"); gremlinClient.execute("fake query"); - expect(gremlinClient.pendingResults.size()).toBe(3); + expect(gremlinClient.pendingResults.size).toBe(3); }); it("should clean up pending request ids after success", async () => { @@ -89,7 +89,7 @@ describe("Gremlin Client", () => { return requestId; }); await gremlinClient.execute("fake query"); - expect(gremlinClient.pendingResults.size()).toBe(0); + expect(gremlinClient.pendingResults.size).toBe(0); }); it("should log and display error out on unknown requestId", () => { @@ -247,7 +247,7 @@ describe("Gremlin Client", () => { sinon.stub(gremlinClient.client, "executeGremlinQuery").callsFake((query: string): string => requestId); gremlinClient.execute("fake query").finally(() => { try { - expect(gremlinClient.pendingResults.size()).toBe(0); + expect(gremlinClient.pendingResults.size).toBe(0); done(); } catch (e) { done(e); diff --git a/src/Explorer/Graph/GraphExplorerComponent/GremlinClient.ts b/src/Explorer/Graph/GraphExplorerComponent/GremlinClient.ts index ee022b873..575412675 100644 --- a/src/Explorer/Graph/GraphExplorerComponent/GremlinClient.ts +++ b/src/Explorer/Graph/GraphExplorerComponent/GremlinClient.ts @@ -4,7 +4,6 @@ import * as Q from "q"; import { getErrorMessage, handleError } from "../../../Common/ErrorHandlingUtils"; -import { HashMap } from "../../../Common/HashMap"; import { logConsoleInfo } from "../../../Utils/NotificationConsoleUtils"; import { GremlinSimpleClient, Result } from "./GremlinSimpleClient"; @@ -30,7 +29,7 @@ interface PendingResultData { export class GremlinClient { public client: GremlinSimpleClient; - public pendingResults: HashMap; // public for testing purposes + public pendingResults: Map; // public for testing purposes private maxResultSize: number; private static readonly PENDING_REQUEST_TIMEOUT_MS = 6 /* minutes */ * 60 /* seconds */ * 1000 /* ms */; private static readonly TIMEOUT_ERROR_MSG = `Pending request timed out (${GremlinClient.PENDING_REQUEST_TIMEOUT_MS} ms)`; @@ -38,7 +37,7 @@ export class GremlinClient { public initialize(params: GremlinClientParameters) { this.destroy(); - this.pendingResults = new HashMap(); + this.pendingResults = new Map(); this.maxResultSize = params.maxResultSize; this.client = new GremlinSimpleClient({ @@ -68,9 +67,9 @@ export class GremlinClient { // Fail all pending requests if no request id (fatal) if (!requestId) { - this.pendingResults.keys().forEach((reqId: string) => { + for (const reqId of this.pendingResults.keys()) { this.abortPendingRequest(reqId, errorMessage, null); - }); + } } } else { this.abortPendingRequest(requestId, errorMessage, result.requestCharge); diff --git a/src/Explorer/Panes/CassandraAddCollectionPane.ts b/src/Explorer/Panes/CassandraAddCollectionPane.ts index 10d644723..d3a2d2098 100644 --- a/src/Explorer/Panes/CassandraAddCollectionPane.ts +++ b/src/Explorer/Panes/CassandraAddCollectionPane.ts @@ -2,7 +2,6 @@ import * as ko from "knockout"; import * as _ from "underscore"; import * as Constants from "../../Common/Constants"; import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils"; -import { HashMap } from "../../Common/HashMap"; import { configContext, Platform } from "../../ConfigContext"; import * as DataModels from "../../Contracts/DataModels"; import * as ViewModels from "../../Contracts/ViewModels"; @@ -51,7 +50,7 @@ export default class CassandraAddCollectionPane extends ContextualPaneBase { public ruToolTipText: ko.Computed; public canConfigureThroughput: ko.PureComputed; - private keyspaceOffers: HashMap; + private keyspaceOffers: Map; constructor(options: ViewModels.PaneOptions) { super(options); @@ -60,7 +59,7 @@ export default class CassandraAddCollectionPane extends ContextualPaneBase { this.keyspaceCreateNew = ko.observable(true); this.ruToolTipText = ko.pureComputed(() => PricingUtils.getRuToolTipText()); this.canConfigureThroughput = ko.pureComputed(() => !this.container.isServerlessEnabled()); - this.keyspaceOffers = new HashMap(); + this.keyspaceOffers = new Map(); this.keyspaceIds = ko.observableArray(); this.keyspaceHasSharedOffer = ko.observable(false); this.keyspaceThroughput = ko.observable(); diff --git a/src/Explorer/Panes/SettingsPane/__snapshots__/SettingsPane.test.tsx.snap b/src/Explorer/Panes/SettingsPane/__snapshots__/SettingsPane.test.tsx.snap index 8344457ad..5915ca240 100644 --- a/src/Explorer/Panes/SettingsPane/__snapshots__/SettingsPane.test.tsx.snap +++ b/src/Explorer/Panes/SettingsPane/__snapshots__/SettingsPane.test.tsx.snap @@ -175,9 +175,7 @@ exports[`Settings Pane should render Default properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -354,9 +352,7 @@ exports[`Settings Pane should render Default properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -470,21 +466,9 @@ exports[`Settings Pane should render Default properly 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { @@ -830,9 +814,7 @@ exports[`Settings Pane should render Gremlin properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -1009,9 +991,7 @@ exports[`Settings Pane should render Gremlin properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -1125,21 +1105,9 @@ exports[`Settings Pane should render Gremlin properly 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { diff --git a/src/Explorer/Panes/StringInputPane/__snapshots__/StringInputPane.test.tsx.snap b/src/Explorer/Panes/StringInputPane/__snapshots__/StringInputPane.test.tsx.snap index eb4b1bfa1..e2ddc5c49 100644 --- a/src/Explorer/Panes/StringInputPane/__snapshots__/StringInputPane.test.tsx.snap +++ b/src/Explorer/Panes/StringInputPane/__snapshots__/StringInputPane.test.tsx.snap @@ -178,9 +178,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -357,9 +355,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -473,21 +469,9 @@ exports[`StringInput Pane should render Create new directory properly 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { @@ -709,9 +693,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -888,9 +870,7 @@ exports[`StringInput Pane should render Create new directory properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -1004,21 +984,9 @@ exports[`StringInput Pane should render Create new directory properly 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { diff --git a/src/Explorer/Panes/UploadItemsPane/__snapshots__/UploadItemsPane.test.tsx.snap b/src/Explorer/Panes/UploadItemsPane/__snapshots__/UploadItemsPane.test.tsx.snap index 8d4b6203c..9bb261343 100644 --- a/src/Explorer/Panes/UploadItemsPane/__snapshots__/UploadItemsPane.test.tsx.snap +++ b/src/Explorer/Panes/UploadItemsPane/__snapshots__/UploadItemsPane.test.tsx.snap @@ -175,9 +175,7 @@ exports[`Upload Items Pane should render Default properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -354,9 +352,7 @@ exports[`Upload Items Pane should render Default properly 1`] = ` "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -470,21 +466,9 @@ exports[`Upload Items Pane should render Default properly 1`] = ` "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { diff --git a/src/Explorer/Panes/__snapshots__/DeleteDatabaseConfirmationPanel.test.tsx.snap b/src/Explorer/Panes/__snapshots__/DeleteDatabaseConfirmationPanel.test.tsx.snap index ac01075ef..e4d8030b5 100644 --- a/src/Explorer/Panes/__snapshots__/DeleteDatabaseConfirmationPanel.test.tsx.snap +++ b/src/Explorer/Panes/__snapshots__/DeleteDatabaseConfirmationPanel.test.tsx.snap @@ -176,9 +176,7 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -355,9 +353,7 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database "keyspaceHasSharedOffer": [Function], "keyspaceId": [Function], "keyspaceIds": [Function], - "keyspaceOffers": HashMap { - "container": Object {}, - }, + "keyspaceOffers": Map {}, "keyspaceThroughput": [Function], "maxThroughputRU": [Function], "minThroughputRU": [Function], @@ -475,21 +471,9 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database "resourceTree": ResourceTreeAdapter { "container": [Circular], "copyNotebook": [Function], - "databaseCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsCollectionIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, - "koSubsDatabaseIdMap": ArrayHashMap { - "store": HashMap { - "container": Object {}, - }, - }, + "databaseCollectionIdMap": Map {}, + "koSubsCollectionIdMap": Map {}, + "koSubsDatabaseIdMap": Map {}, "parameters": [Function], }, "resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken { diff --git a/src/Explorer/Tabs/MongoShellTab.ts b/src/Explorer/Tabs/MongoShellTab.ts index 4ae74947f..15cceff5b 100644 --- a/src/Explorer/Tabs/MongoShellTab.ts +++ b/src/Explorer/Tabs/MongoShellTab.ts @@ -1,6 +1,5 @@ import * as ko from "knockout"; import * as Constants from "../../Common/Constants"; -import { HashMap } from "../../Common/HashMap"; import { configContext, Platform } from "../../ConfigContext"; import * as ViewModels from "../../Contracts/ViewModels"; import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants"; @@ -17,11 +16,11 @@ export default class MongoShellTab extends TabsBase { public url: ko.Computed; private _container: Explorer; private _runtimeEndpoint: string; - private _logTraces: HashMap; + private _logTraces: Map; constructor(options: ViewModels.TabOptions) { super(options); - this._logTraces = new HashMap(); + this._logTraces = new Map(); this._container = options.collection.container; this.url = ko.computed(() => { const account = userContext.databaseAccount; diff --git a/src/Explorer/Tabs/QueryTab.ts b/src/Explorer/Tabs/QueryTab.ts index 976befa21..bf85f257c 100644 --- a/src/Explorer/Tabs/QueryTab.ts +++ b/src/Explorer/Tabs/QueryTab.ts @@ -5,7 +5,6 @@ import * as Constants from "../../Common/Constants"; import { queryDocuments } from "../../Common/dataAccess/queryDocuments"; import { queryDocumentsPage } from "../../Common/dataAccess/queryDocumentsPage"; import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils"; -import { HashMap } from "../../Common/HashMap"; import * as HeadersUtility from "../../Common/HeadersUtility"; import { MinimalQueryIterator } from "../../Common/IteratorUtilities"; import { Splitter, SplitterBounds, SplitterDirection } from "../../Common/Splitter"; @@ -47,7 +46,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem public splitter: Splitter; public isPreferredApiMongoDB: boolean; - public queryMetrics: ko.Observable>; + public queryMetrics: ko.Observable>; public aggregatedQueryMetrics: ko.Observable; public activityId: ko.Observable; public roundTrips: ko.Observable; @@ -91,10 +90,8 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem this.isPreferredApiMongoDB = false; this.aggregatedQueryMetrics = ko.observable(); this._resetAggregateQueryMetrics(); - this.queryMetrics = ko.observable>(new HashMap()); - this.queryMetrics.subscribe((metrics: HashMap) => - this.aggregatedQueryMetrics(this._aggregateQueryMetrics(metrics)) - ); + this.queryMetrics = ko.observable>(new Map()); + this.queryMetrics.subscribe((metrics) => this.aggregatedQueryMetrics(this._aggregateQueryMetrics(metrics))); this.isQueryMetricsEnabled = ko.computed(() => { return userContext.apiType === "SQL" || false; }); @@ -364,13 +361,13 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem this.queryMetrics.valueHasMutated(); } - private _aggregateQueryMetrics(metricsMap: HashMap): DataModels.QueryMetrics { + private _aggregateQueryMetrics(metricsMap: Map): DataModels.QueryMetrics { if (!metricsMap) { return null; } const aggregatedMetrics: DataModels.QueryMetrics = this.aggregatedQueryMetrics(); - metricsMap.forEach((partitionKeyRangeId: string, queryMetrics: DataModels.QueryMetrics) => { + metricsMap.forEach((queryMetrics) => { if (queryMetrics) { aggregatedMetrics.documentLoadTime = queryMetrics.documentLoadTime && @@ -510,7 +507,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem return null; } - const queryMetrics: HashMap = this.queryMetrics(); + const queryMetrics = this.queryMetrics(); let csvData: string = ""; const columnHeaders: string = [ @@ -528,7 +525,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem "Document write time (ms)", ].join(",") + "\n"; csvData = csvData + columnHeaders; - queryMetrics.forEach((partitionKeyRangeId: string, queryMetric: DataModels.QueryMetrics) => { + queryMetrics.forEach((queryMetric, partitionKeyRangeId) => { const partitionKeyRangeData: string = [ partitionKeyRangeId, diff --git a/src/Explorer/Tree/ResourceTreeAdapter.tsx b/src/Explorer/Tree/ResourceTreeAdapter.tsx index 184319ac9..870045a18 100644 --- a/src/Explorer/Tree/ResourceTreeAdapter.tsx +++ b/src/Explorer/Tree/ResourceTreeAdapter.tsx @@ -930,7 +930,7 @@ export class ResourceTreeAdapter implements ReactAdapter { } private cleanupDatabasesKoSubs(): void { - this.koSubsDatabaseIdMap.keys().forEach((databaseId: string) => { + for (const databaseId of this.koSubsDatabaseIdMap.keys()) { this.koSubsDatabaseIdMap.get(databaseId).forEach((sub: ko.Subscription) => sub.dispose()); this.koSubsDatabaseIdMap.delete(databaseId); @@ -939,7 +939,7 @@ export class ResourceTreeAdapter implements ReactAdapter { .get(databaseId) .forEach((collectionId: string) => this.cleanupKoSubsForCollection(databaseId, collectionId)); } - }); + } } private cleanupCollectionsKoSubs(databaseId: string, existingCollectionIds: string[]): void { diff --git a/tsconfig.strict.json b/tsconfig.strict.json index 481ce85d6..d69793c12 100644 --- a/tsconfig.strict.json +++ b/tsconfig.strict.json @@ -14,7 +14,6 @@ "./src/Common/DeleteFeedback.ts", "./src/Common/DocumentUtility.ts", "./src/Common/EnvironmentUtility.ts", - "./src/Common/HashMap.ts", "./src/Common/HeadersUtility.test.ts", "./src/Common/HeadersUtility.ts", "./src/Common/Logger.ts",