diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-09-01 20:27:23 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-09-01 20:27:23 +0100 |
commit | 2f566d6a5ae056498082f029efba5d6e399cc518 (patch) | |
tree | d99605894465eb46bc336679e09ba489978d4fa4 | |
parent | d9d1b7fb0317d9efe121f75b242c8d6e5612eea4 (diff) | |
download | gleam_stdlib-2f566d6a5ae056498082f029efba5d6e399cc518.tar.gz gleam_stdlib-2f566d6a5ae056498082f029efba5d6e399cc518.zip |
Add caching for Map hashcodes
-rw-r--r-- | src/gleam_stdlib.js | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js index df27db2..bc79844 100644 --- a/src/gleam_stdlib.js +++ b/src/gleam_stdlib.js @@ -13,6 +13,8 @@ import { } from "./gleam/regex.js"; import { Some, None } from "./gleam/option.js"; +const HASHCODE_CACHE = new WeakMap(); + const Nil = undefined; export function identity(x) { @@ -259,8 +261,17 @@ export function regex_scan(regex, string) { return List.fromArray(matches); } -export function map_hash(obj) { - return JSON.stringify(obj); +export function hashcode(obj) { + let existing = HASHCODE_CACHE.get(obj); + if (existing) { + return existing; + } else if (obj instanceof Object) { + let hashcode = JSON.stringify(obj); + HASHCODE_CACHE.set(obj, hashcode); + return hashcode; + } else { + return obj.toString(); + } } export function new_map() { @@ -276,40 +287,42 @@ export function map_to_list(map) { } export function map_from_list(list) { - return new Map(list.toArray().map(([a, b]) => [map_hash(a), [a, b]])); + let map = new Map(); + for (let pair of list) { + map.set(hashcode(pair[0]), pair); + } + return map; } export function map_has_key(k, map) { - return map.has(map_hash(k)); + return map.has(hashcode(k)); } export function map_remove(k, map) { const result = new Map(map); - result.delete(map_hash(k)); + result.delete(hashcode(k)); return result; } export function map_filter(f, map) { const result = new Map(); - map.forEach(([key, value], hash) => { - if (f(key)) { - result.set(hash, [key, value]); - } - }) + for (let [hash, [k, v]] of map) { + if (f(k)) result.set(hash, [k, v]); + } return result; } export function map_get(from, get) { - const entry = from.get(map_hash(get)); + const entry = from.get(hashcode(get)); if (entry) { - return new Ok(entry[1]); // [0] is the key, [1] is the value + return new Ok(entry[1]); } else { return new Error(Nil); } } export function map_insert(key, value, map) { - return new Map(map).set(map_hash(key), [key, value]); + return new Map(map).set(hashcode(key), [key, value]); } export function map_keys(map) { @@ -322,7 +335,7 @@ export function map_values(map) { export function map_map_values(fn, map) { const result = new Map(); - map.forEach(([key, value], hash) => result.set(hash, [key, fn(key, value)])); + for (let [hash, [k, v]] of map) result.set(hash, [k, fn(k, v)]); return result; } @@ -332,12 +345,12 @@ export function map_merge(into, merge) { export function map_take(keys, map) { const result = new Map(); - keys.toArray().forEach(key => { - const hash = map_hash(key); + keys.toArray().forEach((key) => { + const hash = hashcode(key); const keyValue = map.get(hash); if (keyValue !== undefined) { result.set(hash, keyValue); } }); return result; -}
\ No newline at end of file +} |