atomic-fns 1.1.6 → 1.2.0
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/README.md +51 -12
- package/dist/collections/BTree.d.ts +11 -10
- package/dist/collections/BTree.js +58 -80
- package/dist/collections/Heap.d.ts +2 -2
- package/dist/collections/Heap.js +1 -1
- package/dist/collections/LRUCache.d.ts +8 -5
- package/dist/collections/LRUCache.js +24 -11
- package/dist/collections/SortedMap.d.ts +4 -4
- package/dist/collections/SortedMap.js +4 -3
- package/dist/collections/SortedSet.d.ts +2 -2
- package/dist/collections/SortedTree.d.ts +9 -9
- package/dist/collections/SortedTree.js +7 -6
- package/dist/collections/SplayTree.d.ts +17 -15
- package/dist/collections/SplayTree.js +42 -29
- package/dist/collections/Trie.d.ts +2 -2
- package/dist/collections/Trie.js +26 -26
- package/dist/collections/deque.d.ts +11 -11
- package/dist/collections/deque.js +17 -10
- package/dist/collections/frozenset.js +4 -1
- package/dist/collections/index.d.ts +30 -48
- package/dist/collections/index.js +210 -82
- package/dist/decimal/index.d.ts +7 -5
- package/dist/decimal/index.js +63 -28
- package/dist/functools/index.d.ts +10 -34
- package/dist/functools/index.js +25 -57
- package/dist/globals/index.d.ts +5 -22
- package/dist/globals/index.js +24 -40
- package/dist/i18n/currency.d.ts +10 -7
- package/dist/i18n/currency.js +22 -7
- package/dist/i18n/date/index.d.ts +22 -16
- package/dist/i18n/date/index.js +89 -67
- package/dist/i18n/date/utils.d.ts +6 -7
- package/dist/i18n/date/utils.js +15 -113
- package/dist/i18n/duration.d.ts +13 -12
- package/dist/i18n/duration.js +38 -32
- package/dist/i18n/format.d.ts +10 -2
- package/dist/i18n/format.js +100 -217
- package/dist/i18n/index.d.ts +2 -1
- package/dist/itertools/index.d.ts +21 -25
- package/dist/itertools/index.js +41 -44
- package/dist/math/index.d.ts +12 -29
- package/dist/math/index.js +16 -33
- package/dist/mod.d.ts +1 -0
- package/dist/mod.js +1 -0
- package/dist/operators/index.d.ts +3 -3
- package/dist/operators/index.js +62 -38
- package/dist/random/index.js +9 -6
- package/dist/string/index.d.ts +1 -1
- package/dist/string/index.js +2 -4
- package/dist/types.d.ts +3 -3
- package/package.json +16 -21
|
@@ -6,6 +6,7 @@ import { Mapping } from './abc.js';
|
|
|
6
6
|
export declare class LRUCache<K = any, V = any> extends Mapping<K, V> {
|
|
7
7
|
protected items: Map<K, V>;
|
|
8
8
|
protected maxSize: number;
|
|
9
|
+
private eviction;
|
|
9
10
|
/**
|
|
10
11
|
* Creates a new instance of fixed size.
|
|
11
12
|
* @param {number} capacity
|
|
@@ -18,6 +19,8 @@ export declare class LRUCache<K = any, V = any> extends Mapping<K, V> {
|
|
|
18
19
|
* @returns {this}
|
|
19
20
|
*/
|
|
20
21
|
set(key: K, value: V): this;
|
|
22
|
+
/** An idle Map iterator pins every hash table the Map has outgrown, so it cannot live forever. */
|
|
23
|
+
private wrote;
|
|
21
24
|
/**
|
|
22
25
|
* This is just an alias of {@link LRUCache.set}.
|
|
23
26
|
* @param {K} key The key to add (note value will be `undefined`)
|
|
@@ -35,7 +38,7 @@ export declare class LRUCache<K = any, V = any> extends Mapping<K, V> {
|
|
|
35
38
|
* @param {K} key
|
|
36
39
|
* @returns {?V} The associated value or `undefined`
|
|
37
40
|
*/
|
|
38
|
-
get(key: K): V;
|
|
41
|
+
get(key: K): V | undefined;
|
|
39
42
|
/**
|
|
40
43
|
* Removes all keys and values from the cache.
|
|
41
44
|
* @returns {this}
|
|
@@ -52,7 +55,7 @@ export declare class LRUCache<K = any, V = any> extends Mapping<K, V> {
|
|
|
52
55
|
* @param {K} key
|
|
53
56
|
* @returns {?V} The value if it was removed or `undefined`.
|
|
54
57
|
*/
|
|
55
|
-
remove(key: K): V;
|
|
58
|
+
remove(key: K): V | undefined;
|
|
56
59
|
/**
|
|
57
60
|
* Returns the total number of elements in the cache.
|
|
58
61
|
*/
|
|
@@ -62,17 +65,17 @@ export declare class LRUCache<K = any, V = any> extends Mapping<K, V> {
|
|
|
62
65
|
*/
|
|
63
66
|
get capacity(): number;
|
|
64
67
|
/**
|
|
65
|
-
* Returns an iterable of all the keys in the cache,
|
|
68
|
+
* Returns an iterable of all the keys in the cache, from least to most recently used.
|
|
66
69
|
* @returns {IterableIterator<K>}
|
|
67
70
|
*/
|
|
68
71
|
keys(): IterableIterator<K>;
|
|
69
72
|
/**
|
|
70
|
-
* Returns an iterable of all the values in the cache,
|
|
73
|
+
* Returns an iterable of all the values in the cache, from least to most recently used.
|
|
71
74
|
* @returns {IterableIterator<V>}
|
|
72
75
|
*/
|
|
73
76
|
values(): IterableIterator<V>;
|
|
74
77
|
/**
|
|
75
|
-
* Returns an iterable of all the [key, value] pairs in the cache,
|
|
78
|
+
* Returns an iterable of all the [key, value] pairs in the cache, from least to most recently used.
|
|
76
79
|
* @returns {IterableIterator<[K, V]>}
|
|
77
80
|
*/
|
|
78
81
|
entries(): IterableIterator<[K, V]>;
|
|
@@ -13,6 +13,8 @@ export class LRUCache extends Mapping {
|
|
|
13
13
|
constructor(capacity = 1024) {
|
|
14
14
|
super();
|
|
15
15
|
this.maxSize = capacity;
|
|
16
|
+
// Not enumerable, so two caches compare by their items
|
|
17
|
+
Object.defineProperty(this, 'eviction', { value: { keys: this.items.keys(), writes: 0 } });
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
20
|
* Adds a new element with a specified `key` and `value` to the cache. If an element with the same key already exists, the element will be updated.
|
|
@@ -21,16 +23,25 @@ export class LRUCache extends Mapping {
|
|
|
21
23
|
* @returns {this}
|
|
22
24
|
*/
|
|
23
25
|
set(key, value) {
|
|
24
|
-
if (this.items.size === this.maxSize) {
|
|
25
|
-
// Because ES6 maps remember insertion order, we can evict the first key
|
|
26
|
-
const lastKey = this.items.keys().next().value;
|
|
27
|
-
this.items.delete(lastKey);
|
|
28
|
-
}
|
|
29
26
|
// Delete the previous key to update the new insertion order
|
|
30
27
|
this.items.delete(key);
|
|
31
28
|
this.items.set(key, value);
|
|
29
|
+
this.wrote();
|
|
30
|
+
if (this.items.size > this.maxSize) {
|
|
31
|
+
// Because ES6 maps remember insertion order, we can evict the first key
|
|
32
|
+
const lastKey = this.eviction.keys.next().value;
|
|
33
|
+
this.items.delete(lastKey);
|
|
34
|
+
}
|
|
32
35
|
return this;
|
|
33
36
|
}
|
|
37
|
+
/** An idle Map iterator pins every hash table the Map has outgrown, so it cannot live forever. */
|
|
38
|
+
wrote() {
|
|
39
|
+
const { eviction } = this;
|
|
40
|
+
if (++eviction.writes >= this.items.size) {
|
|
41
|
+
eviction.writes = 0;
|
|
42
|
+
eviction.keys = this.items.keys();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
34
45
|
/**
|
|
35
46
|
* This is just an alias of {@link LRUCache.set}.
|
|
36
47
|
* @param {K} key The key to add (note value will be `undefined`)
|
|
@@ -58,6 +69,7 @@ export class LRUCache extends Mapping {
|
|
|
58
69
|
// Delete the previous key to update the new insertion order
|
|
59
70
|
this.items.delete(key);
|
|
60
71
|
this.items.set(key, value);
|
|
72
|
+
this.wrote();
|
|
61
73
|
return value;
|
|
62
74
|
}
|
|
63
75
|
}
|
|
@@ -100,25 +112,26 @@ export class LRUCache extends Mapping {
|
|
|
100
112
|
return this.maxSize;
|
|
101
113
|
}
|
|
102
114
|
/**
|
|
103
|
-
* Returns an iterable of all the keys in the cache,
|
|
115
|
+
* Returns an iterable of all the keys in the cache, from least to most recently used.
|
|
104
116
|
* @returns {IterableIterator<K>}
|
|
105
117
|
*/
|
|
106
118
|
keys() {
|
|
107
|
-
|
|
119
|
+
// A snapshot: get and set re-insert keys, so a live Map iterator would never reach the end
|
|
120
|
+
return [...this.items.keys()].values();
|
|
108
121
|
}
|
|
109
122
|
/**
|
|
110
|
-
* Returns an iterable of all the values in the cache,
|
|
123
|
+
* Returns an iterable of all the values in the cache, from least to most recently used.
|
|
111
124
|
* @returns {IterableIterator<V>}
|
|
112
125
|
*/
|
|
113
126
|
values() {
|
|
114
|
-
return this.items.values();
|
|
127
|
+
return [...this.items.values()].values();
|
|
115
128
|
}
|
|
116
129
|
/**
|
|
117
|
-
* Returns an iterable of all the [key, value] pairs in the cache,
|
|
130
|
+
* Returns an iterable of all the [key, value] pairs in the cache, from least to most recently used.
|
|
118
131
|
* @returns {IterableIterator<[K, V]>}
|
|
119
132
|
*/
|
|
120
133
|
entries() {
|
|
121
|
-
return this.items.entries();
|
|
134
|
+
return [...this.items.entries()].values();
|
|
122
135
|
}
|
|
123
136
|
[Symbol.iterator]() {
|
|
124
137
|
return this.entries();
|
|
@@ -24,24 +24,24 @@ export declare class SortedMap<K, V> extends Mapping<K, V> {
|
|
|
24
24
|
* @param {K} key
|
|
25
25
|
* @returns {?V} The key value or `undefined`.
|
|
26
26
|
*/
|
|
27
|
-
get(key: K):
|
|
27
|
+
get(key: K): V | undefined;
|
|
28
28
|
/**
|
|
29
29
|
* Sets the value for the given `key`.
|
|
30
30
|
* @param {K} key
|
|
31
31
|
* @param {V} value
|
|
32
32
|
* @returns {this} Returns the Map object.
|
|
33
33
|
*/
|
|
34
|
-
set(key: K, value: V):
|
|
34
|
+
set(key: K, value: V): this;
|
|
35
35
|
/**
|
|
36
36
|
* Returns the smallest key in the tree.
|
|
37
37
|
* @returns {?K}
|
|
38
38
|
*/
|
|
39
|
-
min(): K;
|
|
39
|
+
min(): K | undefined;
|
|
40
40
|
/**
|
|
41
41
|
* Returns the largest key in the tree.
|
|
42
42
|
* @returns {?K}
|
|
43
43
|
*/
|
|
44
|
-
max(): K;
|
|
44
|
+
max(): K | undefined;
|
|
45
45
|
/**
|
|
46
46
|
* Returns `true` if the `key` existed in the map and was removed.
|
|
47
47
|
* @param {K} key
|
|
@@ -28,7 +28,7 @@ export class SortedMap extends Mapping {
|
|
|
28
28
|
* @returns {this} Returns the Map object.
|
|
29
29
|
*/
|
|
30
30
|
add(key) {
|
|
31
|
-
this.store.
|
|
31
|
+
this.store.add(key);
|
|
32
32
|
return this;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
@@ -46,7 +46,8 @@ export class SortedMap extends Mapping {
|
|
|
46
46
|
* @returns {this} Returns the Map object.
|
|
47
47
|
*/
|
|
48
48
|
set(key, value) {
|
|
49
|
-
|
|
49
|
+
this.store.set(key, value);
|
|
50
|
+
return this;
|
|
50
51
|
}
|
|
51
52
|
/**
|
|
52
53
|
* Returns the smallest key in the tree.
|
|
@@ -68,7 +69,7 @@ export class SortedMap extends Mapping {
|
|
|
68
69
|
* @returns {boolean} `true` if key was removed, otherwise `false`.
|
|
69
70
|
*/
|
|
70
71
|
delete(item) {
|
|
71
|
-
return this.store.
|
|
72
|
+
return this.store.delete(item);
|
|
72
73
|
}
|
|
73
74
|
/**
|
|
74
75
|
* Removes all key/value pairs in the tree.
|
|
@@ -23,12 +23,12 @@ export declare class SortedSet<T> extends Collection {
|
|
|
23
23
|
* Returns the smallest value in the set.
|
|
24
24
|
* @returns {?T}
|
|
25
25
|
*/
|
|
26
|
-
min(): T;
|
|
26
|
+
min(): T | undefined;
|
|
27
27
|
/**
|
|
28
28
|
* Returns the largest value in the set.
|
|
29
29
|
* @returns {?T}
|
|
30
30
|
*/
|
|
31
|
-
max(): T;
|
|
31
|
+
max(): T | undefined;
|
|
32
32
|
/**
|
|
33
33
|
* Removes the value from the set and returns `true` if the value was found and removed.
|
|
34
34
|
* @param {T} value
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Comparer } from '../operators/index.js';
|
|
1
|
+
import type { Comparer } from '../operators/index.js';
|
|
2
2
|
import { Mapping } from './abc.js';
|
|
3
3
|
/**
|
|
4
4
|
* A `SortedTree` is a map that holds key value pairs ordered by keys. Any primitive value (and objects that implement {@link Comparable} or {@link Ordered} interfaces) can be used as keys or values.
|
|
@@ -15,7 +15,7 @@ export declare class SortedTree<K, V> extends Mapping<K, V> {
|
|
|
15
15
|
*/
|
|
16
16
|
constructor(iterable?: Iterable<[K, V]>, compareFn?: Comparer);
|
|
17
17
|
/**
|
|
18
|
-
* Adds a new `key` with a `null` value.
|
|
18
|
+
* Adds a new `key` with a `null` value, if the `key` doesn't exist.
|
|
19
19
|
* @param {K} key
|
|
20
20
|
* @returns {this} Returns the Tree object.
|
|
21
21
|
*/
|
|
@@ -25,7 +25,7 @@ export declare class SortedTree<K, V> extends Mapping<K, V> {
|
|
|
25
25
|
* @param {K} key
|
|
26
26
|
* @returns {?V} The key value or `undefined`.
|
|
27
27
|
*/
|
|
28
|
-
get(key: K): V;
|
|
28
|
+
get(key: K): V | undefined;
|
|
29
29
|
/**
|
|
30
30
|
* Sets the value for the given `key`.
|
|
31
31
|
* @param {K} key
|
|
@@ -37,12 +37,12 @@ export declare class SortedTree<K, V> extends Mapping<K, V> {
|
|
|
37
37
|
* Returns the smallest key in the tree.
|
|
38
38
|
* @returns {?K}
|
|
39
39
|
*/
|
|
40
|
-
min(): K;
|
|
40
|
+
min(): K | undefined;
|
|
41
41
|
/**
|
|
42
42
|
* Returns the largest key in the tree.
|
|
43
43
|
* @returns {?K}
|
|
44
44
|
*/
|
|
45
|
-
max(): K;
|
|
45
|
+
max(): K | undefined;
|
|
46
46
|
/**
|
|
47
47
|
* Returns `true` if the `key` existed in the tree and was removed.
|
|
48
48
|
* @param {K} key
|
|
@@ -60,7 +60,7 @@ export declare class SortedTree<K, V> extends Mapping<K, V> {
|
|
|
60
60
|
freeze(): this;
|
|
61
61
|
/**
|
|
62
62
|
* Returns a new iterator of `[K, V]` pairs in reverse order of keys.
|
|
63
|
-
* @returns {
|
|
63
|
+
* @returns {IterableIterator<[K, V]>}
|
|
64
64
|
*/
|
|
65
65
|
reversed(): IterableIterator<[K, V]>;
|
|
66
66
|
/**
|
|
@@ -87,17 +87,17 @@ export declare class SortedTree<K, V> extends Mapping<K, V> {
|
|
|
87
87
|
has(key: K): boolean;
|
|
88
88
|
/**
|
|
89
89
|
* Returns a new iterator of all **ordered** keys in the tree.
|
|
90
|
-
* @returns {
|
|
90
|
+
* @returns {IterableIterator<K>}
|
|
91
91
|
*/
|
|
92
92
|
keys(): IterableIterator<K>;
|
|
93
93
|
/**
|
|
94
94
|
* Returns a new iterator of all values **ordered** by their keys.
|
|
95
|
-
* @returns {
|
|
95
|
+
* @returns {IterableIterator<V>}
|
|
96
96
|
*/
|
|
97
97
|
values(): IterableIterator<V>;
|
|
98
98
|
/**
|
|
99
99
|
* Returns a new iterator of all key value pairs **ordered** by their keys.
|
|
100
|
-
* @returns {
|
|
100
|
+
* @returns {IterableIterator<[K, V]>}
|
|
101
101
|
*/
|
|
102
102
|
entries(): IterableIterator<[K, V]>;
|
|
103
103
|
}
|
|
@@ -18,12 +18,13 @@ export class SortedTree extends Mapping {
|
|
|
18
18
|
this.store = new BTree(iterable, compareFn);
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* Adds a new `key` with a `null` value.
|
|
21
|
+
* Adds a new `key` with a `null` value, if the `key` doesn't exist.
|
|
22
22
|
* @param {K} key
|
|
23
23
|
* @returns {this} Returns the Tree object.
|
|
24
24
|
*/
|
|
25
25
|
add(key) {
|
|
26
|
-
this.store.
|
|
26
|
+
if (!this.store.contains(key))
|
|
27
|
+
this.store.set(key, null);
|
|
27
28
|
return this;
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
@@ -82,7 +83,7 @@ export class SortedTree extends Mapping {
|
|
|
82
83
|
}
|
|
83
84
|
/**
|
|
84
85
|
* Returns a new iterator of `[K, V]` pairs in reverse order of keys.
|
|
85
|
-
* @returns {
|
|
86
|
+
* @returns {IterableIterator<[K, V]>}
|
|
86
87
|
*/
|
|
87
88
|
reversed() {
|
|
88
89
|
return this.store.reversed();
|
|
@@ -119,21 +120,21 @@ export class SortedTree extends Mapping {
|
|
|
119
120
|
}
|
|
120
121
|
/**
|
|
121
122
|
* Returns a new iterator of all **ordered** keys in the tree.
|
|
122
|
-
* @returns {
|
|
123
|
+
* @returns {IterableIterator<K>}
|
|
123
124
|
*/
|
|
124
125
|
keys() {
|
|
125
126
|
return this.store.keys();
|
|
126
127
|
}
|
|
127
128
|
/**
|
|
128
129
|
* Returns a new iterator of all values **ordered** by their keys.
|
|
129
|
-
* @returns {
|
|
130
|
+
* @returns {IterableIterator<V>}
|
|
130
131
|
*/
|
|
131
132
|
values() {
|
|
132
133
|
return this.store.values();
|
|
133
134
|
}
|
|
134
135
|
/**
|
|
135
136
|
* Returns a new iterator of all key value pairs **ordered** by their keys.
|
|
136
|
-
* @returns {
|
|
137
|
+
* @returns {IterableIterator<[K, V]>}
|
|
137
138
|
*/
|
|
138
139
|
entries() {
|
|
139
140
|
return this.store.entries();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Comparer } from '../operators/index.js';
|
|
1
|
+
import { type Comparer } from '../operators/index.js';
|
|
2
2
|
import { Mapping } from './abc.js';
|
|
3
3
|
/**
|
|
4
4
|
* Base SplayTree node class.
|
|
@@ -10,7 +10,7 @@ declare class Node<K = any, V = any> {
|
|
|
10
10
|
left?: Node<K, V>;
|
|
11
11
|
right?: Node<K, V>;
|
|
12
12
|
constructor(key: K, value: V);
|
|
13
|
-
get height():
|
|
13
|
+
get height(): number;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* A splay tree is a *self-balancing binary* search tree with the additional property that recently accessed elements are quick to access again.
|
|
@@ -31,45 +31,47 @@ export declare class SplayTree<K, V = any> extends Mapping<K, V> {
|
|
|
31
31
|
* @param p When an element is accessed, with probability `p` splay the tree. With probability `1 - p`, leave the tree as it is.
|
|
32
32
|
*/
|
|
33
33
|
constructor(compareFn?: any, p?: number);
|
|
34
|
-
top(): K;
|
|
34
|
+
top(): K | undefined;
|
|
35
35
|
get size(): number;
|
|
36
36
|
empty(): boolean;
|
|
37
|
-
get height():
|
|
37
|
+
get height(): number;
|
|
38
38
|
/**
|
|
39
39
|
* Returns the value for `key` or `undefined` if the key is not found.
|
|
40
40
|
* @param key The key to find.
|
|
41
41
|
* @returns {?V} The value for the key or `undefined`.
|
|
42
42
|
*/
|
|
43
|
-
get(key: K):
|
|
43
|
+
get(key: K): V | undefined;
|
|
44
|
+
private findNode;
|
|
44
45
|
/**
|
|
45
|
-
* Inserts the `key` and `value` in the tree if the `key`
|
|
46
|
+
* Inserts the `key` and `value` in the tree, or updates the value if the `key` exists.
|
|
46
47
|
* @param {K} key A key which can be any comparable value
|
|
47
48
|
* @param {V} value A value associated with the key
|
|
48
49
|
* @returns
|
|
49
50
|
*/
|
|
50
51
|
set(key: K, value: V): void;
|
|
52
|
+
private insert;
|
|
51
53
|
/**
|
|
52
54
|
* Removes a specified key if it exists in the tree. The removed value is returned or `undefined` if not found.
|
|
53
55
|
* @param {K} key The key to remove.
|
|
54
|
-
* @returns {V} The removed value associated with `key`.
|
|
56
|
+
* @returns {?V} The removed value associated with `key`.
|
|
55
57
|
*/
|
|
56
|
-
remove(key: K): V;
|
|
58
|
+
remove(key: K): V | undefined;
|
|
57
59
|
/**
|
|
58
60
|
* Returns the minimum key in the tree or subtree.
|
|
59
61
|
* @returns The minimum key.
|
|
60
62
|
*/
|
|
61
|
-
min(root?: Node<K, V>): K;
|
|
63
|
+
min(root?: Node<K, V>): K | undefined;
|
|
62
64
|
/**
|
|
63
65
|
* Returns the maximum key in the tree or subtree.
|
|
64
66
|
* @returns The maximum key.
|
|
65
67
|
*/
|
|
66
|
-
max(root?: Node<K, V>): K;
|
|
68
|
+
max(root?: Node<K, V>): K | undefined;
|
|
67
69
|
/**
|
|
68
70
|
* Returns the largest key that is less than a given key.
|
|
69
71
|
* @param key The given key
|
|
70
|
-
* @returns The largest key found or `undefined`.
|
|
72
|
+
* @returns {?K} The largest key found or `undefined`.
|
|
71
73
|
*/
|
|
72
|
-
lowerBound(key: any): K |
|
|
74
|
+
lowerBound(key: any): K | undefined;
|
|
73
75
|
/**
|
|
74
76
|
* This is the simplified top-down splaying method proposed by Sleator and Tarjan in {@link https://doi.org/10.1145%2F3828.3835 Self-Adjusting Binary Search Trees}.
|
|
75
77
|
* @param key
|
|
@@ -83,7 +85,7 @@ export declare class SplayTree<K, V = any> extends Mapping<K, V> {
|
|
|
83
85
|
* @returns `true` if found.
|
|
84
86
|
*/
|
|
85
87
|
contains(key: K): boolean;
|
|
86
|
-
/** Alias of remove but
|
|
88
|
+
/** Alias of remove but returns `true` if the key was found instead of the deleted value. */
|
|
87
89
|
delete(key: K): boolean;
|
|
88
90
|
clear(): void;
|
|
89
91
|
/**
|
|
@@ -97,8 +99,8 @@ export declare class SplayTree<K, V = any> extends Mapping<K, V> {
|
|
|
97
99
|
*/
|
|
98
100
|
entries(): Iterable<[K, V]>;
|
|
99
101
|
/**
|
|
100
|
-
* Returns an ordered iterable of all the
|
|
101
|
-
* @returns {Iterable<V>}
|
|
102
|
+
* Returns an ordered iterable of all the values in the tree.
|
|
103
|
+
* @returns {Iterable<V>} An iterable of values sorted by key.
|
|
102
104
|
*/
|
|
103
105
|
values(): Iterable<V>;
|
|
104
106
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { compare
|
|
1
|
+
import { compare } from '../operators/index.js';
|
|
2
2
|
import { Mapping } from './abc.js';
|
|
3
3
|
/**
|
|
4
4
|
* Base SplayTree node class.
|
|
@@ -14,22 +14,29 @@ class Node {
|
|
|
14
14
|
this.value = value;
|
|
15
15
|
}
|
|
16
16
|
get height() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return
|
|
17
|
+
let height = -1;
|
|
18
|
+
let level = [this];
|
|
19
|
+
while (level.length) {
|
|
20
|
+
height += 1;
|
|
21
|
+
level = level.flatMap((node) => [node.left, node.right].filter(Boolean));
|
|
22
|
+
}
|
|
23
|
+
return height;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
// In-order
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
// In-order snapshot of a tree: reads splay it, so a live walk would lose its place
|
|
27
|
+
function traverse(node) {
|
|
28
|
+
const nodes = [];
|
|
29
|
+
const stack = [];
|
|
30
|
+
while (node || stack.length) {
|
|
31
|
+
while (node) {
|
|
32
|
+
stack.push(node);
|
|
33
|
+
node = node.left;
|
|
34
|
+
}
|
|
35
|
+
node = stack.pop();
|
|
36
|
+
nodes.push(node);
|
|
31
37
|
node = node.right;
|
|
32
38
|
}
|
|
39
|
+
return nodes;
|
|
33
40
|
}
|
|
34
41
|
/**
|
|
35
42
|
* A splay tree is a *self-balancing binary* search tree with the additional property that recently accessed elements are quick to access again.
|
|
@@ -75,6 +82,9 @@ export class SplayTree extends Mapping {
|
|
|
75
82
|
* @returns {?V} The value for the key or `undefined`.
|
|
76
83
|
*/
|
|
77
84
|
get(key) {
|
|
85
|
+
return this.findNode(key)?.value;
|
|
86
|
+
}
|
|
87
|
+
findNode(key) {
|
|
78
88
|
if (!this.root)
|
|
79
89
|
return;
|
|
80
90
|
// Note: deterministic splaying (always moves key to front):
|
|
@@ -86,7 +96,7 @@ export class SplayTree extends Mapping {
|
|
|
86
96
|
if (Math.random() <= this.randSplay) {
|
|
87
97
|
this.splay(key);
|
|
88
98
|
if (this.cmp(key, this.root.key) === 0)
|
|
89
|
-
return this.root
|
|
99
|
+
return this.root;
|
|
90
100
|
else
|
|
91
101
|
return undefined;
|
|
92
102
|
}
|
|
@@ -95,7 +105,7 @@ export class SplayTree extends Mapping {
|
|
|
95
105
|
while (current) {
|
|
96
106
|
const rank = this.cmp(key, current.key);
|
|
97
107
|
if (rank === 0)
|
|
98
|
-
return current
|
|
108
|
+
return current;
|
|
99
109
|
if (rank < 0)
|
|
100
110
|
current = current.left;
|
|
101
111
|
else
|
|
@@ -103,12 +113,15 @@ export class SplayTree extends Mapping {
|
|
|
103
113
|
}
|
|
104
114
|
}
|
|
105
115
|
/**
|
|
106
|
-
* Inserts the `key` and `value` in the tree if the `key`
|
|
116
|
+
* Inserts the `key` and `value` in the tree, or updates the value if the `key` exists.
|
|
107
117
|
* @param {K} key A key which can be any comparable value
|
|
108
118
|
* @param {V} value A value associated with the key
|
|
109
119
|
* @returns
|
|
110
120
|
*/
|
|
111
121
|
set(key, value) {
|
|
122
|
+
this.insert(key, value, true);
|
|
123
|
+
}
|
|
124
|
+
insert(key, value, overwrite) {
|
|
112
125
|
if (!this.root) {
|
|
113
126
|
this.root = new Node(key, value);
|
|
114
127
|
this.count += 1;
|
|
@@ -120,7 +133,8 @@ export class SplayTree extends Mapping {
|
|
|
120
133
|
const rank = this.cmp(key, this.root.key);
|
|
121
134
|
if (rank === 0) {
|
|
122
135
|
// Update the value
|
|
123
|
-
|
|
136
|
+
if (overwrite)
|
|
137
|
+
this.root.value = value;
|
|
124
138
|
return;
|
|
125
139
|
}
|
|
126
140
|
const node = new Node(key, value);
|
|
@@ -140,14 +154,14 @@ export class SplayTree extends Mapping {
|
|
|
140
154
|
/**
|
|
141
155
|
* Removes a specified key if it exists in the tree. The removed value is returned or `undefined` if not found.
|
|
142
156
|
* @param {K} key The key to remove.
|
|
143
|
-
* @returns {V} The removed value associated with `key`.
|
|
157
|
+
* @returns {?V} The removed value associated with `key`.
|
|
144
158
|
*/
|
|
145
159
|
remove(key) {
|
|
146
160
|
if (!this.root) {
|
|
147
161
|
return;
|
|
148
162
|
}
|
|
149
163
|
this.splay(key);
|
|
150
|
-
if (
|
|
164
|
+
if (this.cmp(key, this.root.key) !== 0) {
|
|
151
165
|
return;
|
|
152
166
|
}
|
|
153
167
|
const removed = this.root;
|
|
@@ -203,7 +217,7 @@ export class SplayTree extends Mapping {
|
|
|
203
217
|
/**
|
|
204
218
|
* Returns the largest key that is less than a given key.
|
|
205
219
|
* @param key The given key
|
|
206
|
-
* @returns The largest key found or `undefined`.
|
|
220
|
+
* @returns {?K} The largest key found or `undefined`.
|
|
207
221
|
*/
|
|
208
222
|
lowerBound(key) {
|
|
209
223
|
if (!this.root)
|
|
@@ -214,7 +228,7 @@ export class SplayTree extends Mapping {
|
|
|
214
228
|
// Now the result is either the root node or the greatest node in
|
|
215
229
|
// the left subtree.
|
|
216
230
|
if (this.cmp(this.root.key, key) < 0) {
|
|
217
|
-
return this.root;
|
|
231
|
+
return this.root.key;
|
|
218
232
|
}
|
|
219
233
|
else if (this.root.left) {
|
|
220
234
|
return this.max(this.root.left);
|
|
@@ -229,7 +243,6 @@ export class SplayTree extends Mapping {
|
|
|
229
243
|
if (!this.root)
|
|
230
244
|
return;
|
|
231
245
|
let stub, left, right;
|
|
232
|
-
// eslint-disable-next-line
|
|
233
246
|
stub = left = right = new Node(null, null);
|
|
234
247
|
let root = this.root;
|
|
235
248
|
while (true) {
|
|
@@ -284,7 +297,7 @@ export class SplayTree extends Mapping {
|
|
|
284
297
|
this.root = root;
|
|
285
298
|
}
|
|
286
299
|
add(key) {
|
|
287
|
-
|
|
300
|
+
this.insert(key, null, false);
|
|
288
301
|
}
|
|
289
302
|
/**
|
|
290
303
|
* Returns `true` if the given key is in the tree.
|
|
@@ -292,13 +305,13 @@ export class SplayTree extends Mapping {
|
|
|
292
305
|
* @returns `true` if found.
|
|
293
306
|
*/
|
|
294
307
|
contains(key) {
|
|
295
|
-
return this.
|
|
308
|
+
return this.findNode(key) !== undefined;
|
|
296
309
|
}
|
|
297
|
-
/** Alias of remove but
|
|
310
|
+
/** Alias of remove but returns `true` if the key was found instead of the deleted value. */
|
|
298
311
|
delete(key) {
|
|
299
|
-
|
|
312
|
+
const size = this.count;
|
|
300
313
|
this.remove(key);
|
|
301
|
-
return
|
|
314
|
+
return this.count < size;
|
|
302
315
|
}
|
|
303
316
|
clear() {
|
|
304
317
|
if (!this.root)
|
|
@@ -327,8 +340,8 @@ export class SplayTree extends Mapping {
|
|
|
327
340
|
}
|
|
328
341
|
}
|
|
329
342
|
/**
|
|
330
|
-
* Returns an ordered iterable of all the
|
|
331
|
-
* @returns {Iterable<V>}
|
|
343
|
+
* Returns an ordered iterable of all the values in the tree.
|
|
344
|
+
* @returns {Iterable<V>} An iterable of values sorted by key.
|
|
332
345
|
*/
|
|
333
346
|
*values() {
|
|
334
347
|
for (const node of traverse(this.root)) {
|
|
@@ -23,9 +23,9 @@ export declare class Trie extends Collection {
|
|
|
23
23
|
/**
|
|
24
24
|
* Generates all results that start with the given string.
|
|
25
25
|
* @param word A prefix string
|
|
26
|
-
* @param {number} [limit
|
|
26
|
+
* @param {number} [limit] The number of results to return. Defaults to every result.
|
|
27
27
|
*/
|
|
28
|
-
matches: (word: string, limit?: number) => Generator<
|
|
28
|
+
matches: (word: string, limit?: number) => Generator<string>;
|
|
29
29
|
/**
|
|
30
30
|
* Returns `true` if the given string is found in the tree.
|
|
31
31
|
* @param {string} word
|