{"ScriptPreparationCode":"\u0022use-strict\u0022;\r\n\r\nconst HASH_SIZE = 64,\r\n FNV_PRIME_64 = 1099511628211n,\r\n FNV_OFFSET_64 = 14695981039346656037n;\r\n\r\nlet char;\r\nfunction FNV1aHash64(string) {\r\n const { length } = string;\r\n let hash = FNV_OFFSET_64,\r\n i = 0;\r\n for (\r\n ;\r\n i \u003C length;\r\n char = BigInt(string.charCodeAt(i\u002B\u002B)),\r\n hash = BigInt.asUintN(HASH_SIZE, (hash ^ char) * FNV_PRIME_64)\r\n );\r\n return hash;\r\n}\r\n\r\nconst DEFAULT_TABLE_SIZE_L_SHIFT = 9;\r\n\r\nfunction fastRemoveElem(arr, i) {\r\n const tmp = arr[arr.length - 1];\r\n arr[arr.length - 1] = arr[i];\r\n arr[i] = tmp;\r\n arr.pop();\r\n}\r\n\r\n// TODO: use mersenne primes for table size\r\n// TODO: handle grow\r\n// TODO: values method\r\nclass FastStringMap {\r\n constructor() {\r\n this._size_factor = DEFAULT_TABLE_SIZE_L_SHIFT;\r\n const capacity = 0x2 \u003C\u003C this._size_factor;\r\n this._capacity = BigInt(capacity);\r\n this._table = new Array(capacity);\r\n this.size = 0;\r\n }\r\n\r\n _indexOfKey(key) {\r\n return FNV1aHash64(key) \u0026 (this._capacity - 1n);\r\n }\r\n\r\n /**\r\n * @param key unique key\r\n * @returns the value stored in the key, or undefined if it doesnt exist\r\n */\r\n get(key) {\r\n const bucket = this._table[this._indexOfKey(key)];\r\n if (!bucket) {\r\n return undefined;\r\n }\r\n let { length } = bucket,\r\n i = 0;\r\n for (; i \u003C length; \u002B\u002Bi) {\r\n if (bucket[i][0] === key) {\r\n return bucket[i][1];\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * @param key unique key\r\n * @param value the value to store\r\n * @returns this\r\n */\r\n set(key, value) {\r\n let bucket,\r\n table = this._table,\r\n index = this._indexOfKey(key);\r\n if ((bucket = table[index]) !== undefined) {\r\n bucket.push([key, value]);\r\n } else {\r\n table[index] = [[key, value]];\r\n }\r\n \u002B\u002Bthis.size;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param key unique key\r\n * @returns this\r\n */\r\n remove(key) {\r\n const bucket = this._table[this._indexOfKey(key)];\r\n if (!bucket) {\r\n return this;\r\n }\r\n let { length } = bucket,\r\n i = 0;\r\n for (; i \u003C length; \u002B\u002Bi) {\r\n if (bucket[i][0] === key) {\r\n fastRemoveElem(bucket, i);\r\n return this;\r\n }\r\n }\r\n return this;\r\n }\r\n}\r\n\r\nvar fastStringMap = new FastStringMap();\r\nvar map = new Map();\r\nvar obj = {};","TestCases":[{"Name":"test map","Code":"for(let i=0; i\u003C100; \u002B\u002Bi){\r\n map.set(i.toString(), i);\r\n}\r\nfor(let i=0; i\u003C100000; \u002B\u002Bi){\r\n map.get(i.toString());\r\n}","IsDeferred":false},{"Name":"test fast string map","Code":"for(let i=0; i\u003C100; \u002B\u002Bi){\r\n fastStringMap.set(i.toString(), i);\r\n}\r\nfor(let i=0; i\u003C100000; \u002B\u002Bi){\r\n fastStringMap.get(i.toString());\r\n}","IsDeferred":false},{"Name":"test set map","Code":"for(let i=0; i\u003C100; \u002B\u002Bi){\r\n map.set(i.toString(), i);\r\n}","IsDeferred":false},{"Name":"test set fast string map","Code":"for(let i=0; i\u003C100; \u002B\u002Bi){\r\n fastStringMap.set(i.toString(), i);\r\n}","IsDeferred":false},{"Name":"obj","Code":"for(let i=0; i\u003C100; \u002B\u002Bi){\r\n obj[i] = i;\r\n}\r\nfor(let i=0; i\u003C100000; \u002B\u002Bi){\r\n obj[i];\r\n}","IsDeferred":false}]}