atomic-fns 0.3.1 → 0.3.3
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/.esdoc.json +2 -2
- package/README.md +48 -13
- package/core/collections/BTree.d.ts +229 -0
- package/core/collections/BTree.js +1165 -0
- package/core/collections/BTree.ts +1340 -0
- package/core/collections/Heap.d.ts +69 -0
- package/core/collections/Heap.js +181 -0
- package/core/collections/Heap.ts +189 -0
- package/core/collections/LRUCache.d.ts +131 -0
- package/core/collections/LRUCache.js +388 -0
- package/core/collections/LRUCache.ts +465 -0
- package/core/collections/SortedMap.d.ts +92 -0
- package/core/collections/SortedMap.js +130 -0
- package/core/collections/SortedMap.ts +146 -0
- package/core/collections/SortedSet.d.ts +63 -0
- package/core/collections/SortedSet.js +93 -0
- package/core/collections/SortedSet.ts +104 -0
- package/core/collections/SortedTree.d.ts +103 -0
- package/core/collections/SortedTree.js +141 -0
- package/core/collections/SortedTree.ts +160 -0
- package/core/collections/SplayTree.d.ts +105 -0
- package/core/collections/SplayTree.js +338 -0
- package/core/collections/SplayTree.ts +354 -0
- package/core/collections/abc.d.ts +152 -0
- package/core/collections/abc.js +39 -0
- package/core/collections/abc.ts +176 -0
- package/core/collections/deque.d.ts +110 -0
- package/core/collections/deque.js +285 -0
- package/core/collections/deque.ts +329 -0
- package/core/collections/frozenset.d.ts +19 -0
- package/core/collections/frozenset.js +33 -0
- package/core/collections/frozenset.ts +37 -0
- package/{src → core}/collections/index.d.ts +41 -162
- package/{src → core}/collections/index.js +57 -165
- package/{src → core}/collections/index.ts +61 -225
- package/core/collections/test.html +10 -0
- package/core/collections/typedArrays.d.ts +31 -0
- package/core/collections/typedArrays.js +143 -0
- package/core/collections/typedArrays.ts +163 -0
- package/core/datetime/index.d.ts +45 -0
- package/core/datetime/index.js +71 -0
- package/core/datetime/index.ts +128 -0
- package/{src → core}/functools/index.d.ts +2 -2
- package/{src → core}/functools/index.js +2 -2
- package/{src → core}/functools/index.ts +2 -2
- package/{src → core}/globals/index.d.ts +2 -7
- package/{src → core}/globals/index.js +5 -2
- package/{src → core}/globals/index.ts +6 -9
- package/{src → core}/index.d.ts +0 -1
- package/{src → core}/index.js +0 -1
- package/{src → core}/index.ts +0 -1
- package/{src → core}/itertools/index.d.ts +9 -7
- package/{src → core}/itertools/index.js +25 -9
- package/{src → core}/itertools/index.ts +39 -16
- package/{src → core}/math/index.d.ts +0 -0
- package/{src → core}/math/index.js +0 -0
- package/{src → core}/math/index.ts +0 -0
- package/core/operators/index.d.ts +148 -0
- package/core/operators/index.js +271 -0
- package/core/operators/index.ts +282 -0
- package/{src → core}/random/index.d.ts +0 -0
- package/{src → core}/random/index.js +0 -0
- package/{src → core}/random/index.ts +0 -0
- package/package.json +6 -6
- package/tests/BTree.spec.ts +143 -0
- package/tests/Cache.spec.ts +161 -0
- package/tests/Heap.spec.ts +66 -0
- package/tests/SortedMap.spec.ts +144 -0
- package/tests/SortedSet.spec.ts +84 -0
- package/tests/SortedTree.spec.ts +164 -0
- package/tests/SplayTree.spec.ts +121 -0
- package/tests/collections.spec.ts +1 -1
- package/tests/deque.spec.ts +107 -0
- package/tests/globals.spec.ts +2 -2
- package/tests/itertools.spec.ts +2 -2
- package/tests/math.spec.ts +1 -1
- package/tests/operators.spec.ts +5 -5
- package/tests/random.spec.ts +10 -10
- package/tsconfig.json +10 -10
- package/tsconfig.node.json +2 -2
- package/tsconfig.xo.json +2 -2
- package/src/datetime/index.d.ts +0 -6
- package/src/datetime/index.js +0 -6
- package/src/datetime/index.ts +0 -7
- package/src/operators/index.d.ts +0 -31
- package/src/operators/index.js +0 -171
- package/src/operators/index.ts +0 -175
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import { Iteratee, NotImplementedError, ValueError } from '../globals/index.js'
|
|
2
|
+
import { IterableIterator } from '../itertools/index.js'
|
|
3
|
+
import { Mapping } from './abc.js'
|
|
4
|
+
import { getPointerArray } from './typedArrays.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base append-only Cache collection.
|
|
8
|
+
*/
|
|
9
|
+
export class Cache<K, V = any> extends Mapping<K, V> {
|
|
10
|
+
capacity: number
|
|
11
|
+
head: number = 0
|
|
12
|
+
tail: number = 0
|
|
13
|
+
count: number = 0
|
|
14
|
+
protected items = new Map<K, number>()
|
|
15
|
+
protected forward: Uint8Array | Uint16Array | Uint32Array
|
|
16
|
+
protected backward: Uint8Array | Uint16Array | Uint32Array
|
|
17
|
+
protected K: K[]
|
|
18
|
+
protected V: V[]
|
|
19
|
+
|
|
20
|
+
constructor(capacity = 1024, Keys = Array, Values = Array) {
|
|
21
|
+
super()
|
|
22
|
+
this.capacity = capacity
|
|
23
|
+
|
|
24
|
+
if (typeof this.capacity !== 'number' || this.capacity <= 0)
|
|
25
|
+
throw new ValueError('LRUCache capacity should be a positive integer.')
|
|
26
|
+
else if (!isFinite(this.capacity) || Math.floor(this.capacity) !== this.capacity)
|
|
27
|
+
throw new ValueError('LRUCache capacity should be a finite positive integer.')
|
|
28
|
+
|
|
29
|
+
const PointerArray = getPointerArray(capacity)
|
|
30
|
+
this.forward = new PointerArray(capacity)
|
|
31
|
+
this.backward = new PointerArray(capacity)
|
|
32
|
+
this.K = new Keys(capacity)
|
|
33
|
+
this.V = new Values(capacity)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* This is just an alias of {@link Cache.set}.
|
|
38
|
+
* @param {K} key The key to add (note value will be `undefined`).
|
|
39
|
+
*/
|
|
40
|
+
add(key: K) {
|
|
41
|
+
return this.set(key, undefined)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Method used to check whether the key exists in the cache.
|
|
46
|
+
*
|
|
47
|
+
* @param {any} key - Key.
|
|
48
|
+
* @return {boolean}
|
|
49
|
+
*/
|
|
50
|
+
contains(key) {
|
|
51
|
+
return this.items.has(key)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Method used to clear the structure.
|
|
56
|
+
*/
|
|
57
|
+
clear() {
|
|
58
|
+
this.count = 0
|
|
59
|
+
this.head = 0
|
|
60
|
+
this.tail = 0
|
|
61
|
+
this.items = new Map()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get size() {
|
|
65
|
+
return this.count
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Method used to splay a value on top.
|
|
70
|
+
*
|
|
71
|
+
* @param {number} pointer - Pointer of the value to splay on top.
|
|
72
|
+
* @return {Cache}
|
|
73
|
+
*/
|
|
74
|
+
protected splayOnTop(pointer) {
|
|
75
|
+
const oldHead = this.head
|
|
76
|
+
|
|
77
|
+
if (this.head === pointer) return this
|
|
78
|
+
|
|
79
|
+
const previous = this.backward[pointer]
|
|
80
|
+
const next = this.forward[pointer]
|
|
81
|
+
|
|
82
|
+
if (this.tail === pointer) {
|
|
83
|
+
this.tail = previous
|
|
84
|
+
} else {
|
|
85
|
+
this.backward[next] = previous
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this.forward[previous] = next
|
|
89
|
+
|
|
90
|
+
this.backward[oldHead] = pointer
|
|
91
|
+
this.head = pointer
|
|
92
|
+
this.forward[pointer] = oldHead
|
|
93
|
+
|
|
94
|
+
return this
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Method used to get the value attached to the given key. Will move the
|
|
99
|
+
* related key to the front of the underlying linked list.
|
|
100
|
+
*
|
|
101
|
+
* @param {any} key - Key.
|
|
102
|
+
* @return {any}
|
|
103
|
+
*/
|
|
104
|
+
get(key) {
|
|
105
|
+
const pointer = this.items.get(key)
|
|
106
|
+
|
|
107
|
+
if (typeof pointer === 'undefined') return
|
|
108
|
+
|
|
109
|
+
this.splayOnTop(pointer)
|
|
110
|
+
|
|
111
|
+
return this.V[pointer]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Method used to set the value for the given key in the cache.
|
|
116
|
+
*
|
|
117
|
+
* @param {any} key - Key.
|
|
118
|
+
* @param {any} value - Value.
|
|
119
|
+
* @return {undefined}
|
|
120
|
+
*/
|
|
121
|
+
set(key, value) {
|
|
122
|
+
let pointer = this.items.get(key)
|
|
123
|
+
|
|
124
|
+
// The key already exists, we just need to update the value and splay on top
|
|
125
|
+
if (typeof pointer !== 'undefined') {
|
|
126
|
+
this.splayOnTop(pointer)
|
|
127
|
+
this.V[pointer] = value
|
|
128
|
+
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// The cache is not yet full
|
|
133
|
+
if (this.count < this.capacity) {
|
|
134
|
+
pointer = this.count++
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Cache is full, we need to drop the last value
|
|
138
|
+
else {
|
|
139
|
+
pointer = this.tail
|
|
140
|
+
this.tail = this.backward[pointer]
|
|
141
|
+
this.items.delete(this.K[pointer])
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Storing key & value
|
|
145
|
+
this.items.set(key, pointer)
|
|
146
|
+
this.K[pointer] = key
|
|
147
|
+
this.V[pointer] = value
|
|
148
|
+
|
|
149
|
+
// Moving the item at the front of the list
|
|
150
|
+
this.forward[pointer] = this.head
|
|
151
|
+
this.backward[this.head] = pointer
|
|
152
|
+
this.head = pointer
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Method used to get the value attached to the given key. Does not modify
|
|
157
|
+
* the ordering of the underlying linked list.
|
|
158
|
+
*
|
|
159
|
+
* @param {any} key - Key.
|
|
160
|
+
* @return {any}
|
|
161
|
+
*/
|
|
162
|
+
peek(key) {
|
|
163
|
+
const pointer = this.items.get(key)
|
|
164
|
+
|
|
165
|
+
if (typeof pointer === 'undefined') return
|
|
166
|
+
|
|
167
|
+
return this.V[pointer]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Method used to iterate over the cache's entries using a callback.
|
|
172
|
+
*
|
|
173
|
+
* @param {Iteratee<V>} iteratee - Function to call for each item.
|
|
174
|
+
*/
|
|
175
|
+
forEach(iteratee: Iteratee<V>) {
|
|
176
|
+
let i = 0
|
|
177
|
+
const l = this.count
|
|
178
|
+
|
|
179
|
+
let pointer = this.head
|
|
180
|
+
const keys = this.K
|
|
181
|
+
const values = this.V
|
|
182
|
+
const forward = this.forward
|
|
183
|
+
|
|
184
|
+
while (i < l) {
|
|
185
|
+
iteratee(values[pointer], keys[pointer], this)
|
|
186
|
+
pointer = forward[pointer]
|
|
187
|
+
i++
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Method used to create an iterator over the cache's keys from most
|
|
193
|
+
* recently used to least recently used.
|
|
194
|
+
*
|
|
195
|
+
* @return {Iterator<K>}
|
|
196
|
+
*/
|
|
197
|
+
keys() {
|
|
198
|
+
let i = 0
|
|
199
|
+
const l = this.count
|
|
200
|
+
|
|
201
|
+
let pointer = this.head
|
|
202
|
+
const keys = this.K
|
|
203
|
+
const forward = this.forward
|
|
204
|
+
|
|
205
|
+
return IterableIterator(() => {
|
|
206
|
+
if (i >= l) return { done: true }
|
|
207
|
+
|
|
208
|
+
const key = keys[pointer]
|
|
209
|
+
|
|
210
|
+
i++
|
|
211
|
+
|
|
212
|
+
if (i < l) pointer = forward[pointer]
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
done: false,
|
|
216
|
+
value: key
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Method used to create an iterator over the cache's values from most
|
|
223
|
+
* recently used to least recently used.
|
|
224
|
+
*
|
|
225
|
+
* @return {Iterator<V>}
|
|
226
|
+
*/
|
|
227
|
+
values() {
|
|
228
|
+
let i = 0
|
|
229
|
+
const l = this.count
|
|
230
|
+
|
|
231
|
+
let pointer = this.head
|
|
232
|
+
const values = this.V
|
|
233
|
+
const forward = this.forward
|
|
234
|
+
|
|
235
|
+
return IterableIterator(() => {
|
|
236
|
+
if (i >= l) return { done: true }
|
|
237
|
+
|
|
238
|
+
const value = values[pointer]
|
|
239
|
+
|
|
240
|
+
i++
|
|
241
|
+
|
|
242
|
+
if (i < l) pointer = forward[pointer]
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
done: false,
|
|
246
|
+
value
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Method used to create an iterator over the cache's entries from most
|
|
253
|
+
* recently used to least recently used.
|
|
254
|
+
*
|
|
255
|
+
* @return {Iterator<[K, V]>}
|
|
256
|
+
*/
|
|
257
|
+
entries() {
|
|
258
|
+
let i = 0
|
|
259
|
+
const l = this.count
|
|
260
|
+
|
|
261
|
+
let pointer = this.head
|
|
262
|
+
const keys = this.K
|
|
263
|
+
const values = this.V
|
|
264
|
+
const forward = this.forward
|
|
265
|
+
|
|
266
|
+
return IterableIterator<[K, V]>(() => {
|
|
267
|
+
if (i >= l) return { done: true }
|
|
268
|
+
|
|
269
|
+
const key = keys[pointer]
|
|
270
|
+
const value = values[pointer]
|
|
271
|
+
|
|
272
|
+
i++
|
|
273
|
+
|
|
274
|
+
if (i < l) pointer = forward[pointer]
|
|
275
|
+
|
|
276
|
+
return { value: [key, value] }
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* NotImplemented -- throws an exception.
|
|
282
|
+
* @param key
|
|
283
|
+
* @returns
|
|
284
|
+
*/
|
|
285
|
+
remove(key: any) {
|
|
286
|
+
throw new NotImplementedError(`Base Cache class does not implement remove().`)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
[Symbol.iterator]() {
|
|
290
|
+
return this.entries()
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Convenience known methods.
|
|
295
|
+
*/
|
|
296
|
+
inspect() {
|
|
297
|
+
const proxy = new Map()
|
|
298
|
+
|
|
299
|
+
const iterator = this.entries()
|
|
300
|
+
let step
|
|
301
|
+
|
|
302
|
+
while (((step = iterator.next()), !step.done)) proxy.set(step.value[0], step.value[1])
|
|
303
|
+
|
|
304
|
+
// Trick so that node displays the name of the constructor
|
|
305
|
+
Object.defineProperty(proxy, 'constructor', {
|
|
306
|
+
value: Cache,
|
|
307
|
+
enumerable: false
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
return proxy
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
314
|
+
return this.inspect()
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export class LRUCache<K, V> extends Cache<K, V> {
|
|
319
|
+
deletedSize = 0
|
|
320
|
+
deleted: Uint8Array | Uint16Array | Uint32Array
|
|
321
|
+
|
|
322
|
+
constructor(capacity = 1024, Keys = Array, Values = Array) {
|
|
323
|
+
super(capacity, Keys, Values)
|
|
324
|
+
const PointerArray = getPointerArray(capacity)
|
|
325
|
+
this.deleted = new PointerArray(capacity)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
clear() {
|
|
329
|
+
super.clear()
|
|
330
|
+
this.deletedSize = 0
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Method used to set the value for the given key in the cache.
|
|
335
|
+
*
|
|
336
|
+
* @param {any} key - Key.
|
|
337
|
+
* @param {any} value - Value.
|
|
338
|
+
* @return {undefined}
|
|
339
|
+
*/
|
|
340
|
+
set(key, value) {
|
|
341
|
+
let pointer = this.items.get(key)
|
|
342
|
+
|
|
343
|
+
// The key already exists, we just need to update the value and splay on top
|
|
344
|
+
if (typeof pointer !== 'undefined') {
|
|
345
|
+
this.splayOnTop(pointer)
|
|
346
|
+
this.V[pointer] = value
|
|
347
|
+
|
|
348
|
+
return
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// The cache is not yet full
|
|
352
|
+
if (this.count < this.capacity) {
|
|
353
|
+
if (this.deletedSize > 0) {
|
|
354
|
+
// If there is a "hole" in the pointer list, reuse it
|
|
355
|
+
pointer = this.deleted[--this.deletedSize]
|
|
356
|
+
} else {
|
|
357
|
+
// otherwise append to the pointer list
|
|
358
|
+
pointer = this.count
|
|
359
|
+
}
|
|
360
|
+
this.count++
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Cache is full, we need to drop the last value
|
|
364
|
+
else {
|
|
365
|
+
pointer = this.tail
|
|
366
|
+
this.tail = this.backward[pointer]
|
|
367
|
+
this.items.delete(this.K[pointer])
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Storing key & value
|
|
371
|
+
this.items.set(key, pointer)
|
|
372
|
+
this.K[pointer] = key
|
|
373
|
+
this.V[pointer] = value
|
|
374
|
+
|
|
375
|
+
// Moving the item at the front of the list
|
|
376
|
+
this.forward[pointer] = this.head
|
|
377
|
+
this.backward[this.head] = pointer
|
|
378
|
+
this.head = pointer
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Method used to delete the entry for the given key in the cache.
|
|
383
|
+
*
|
|
384
|
+
* @param {any} key - Key.
|
|
385
|
+
* @return {boolean} - true if the item was present
|
|
386
|
+
*/
|
|
387
|
+
delete(key) {
|
|
388
|
+
const pointer = this.items.get(key)
|
|
389
|
+
|
|
390
|
+
if (typeof pointer === 'undefined') {
|
|
391
|
+
return false
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
this.items.delete(key)
|
|
395
|
+
|
|
396
|
+
if (this.count === 1) {
|
|
397
|
+
this.count = 0
|
|
398
|
+
this.head = 0
|
|
399
|
+
this.tail = 0
|
|
400
|
+
this.deletedSize = 0
|
|
401
|
+
return true
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const previous = this.backward[pointer]
|
|
405
|
+
const next = this.forward[pointer]
|
|
406
|
+
|
|
407
|
+
if (this.head === pointer) {
|
|
408
|
+
this.head = next
|
|
409
|
+
}
|
|
410
|
+
if (this.tail === pointer) {
|
|
411
|
+
this.tail = previous
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
this.forward[previous] = next
|
|
415
|
+
this.backward[next] = previous
|
|
416
|
+
|
|
417
|
+
this.count--
|
|
418
|
+
this.deleted[this.deletedSize++] = pointer
|
|
419
|
+
|
|
420
|
+
return true
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Method used to remove and return the value for the given key in the cache.
|
|
425
|
+
*
|
|
426
|
+
* @param {any} key - Key.
|
|
427
|
+
* @return {any} The value, if present; the missing indicator if absent
|
|
428
|
+
*/
|
|
429
|
+
remove(key) {
|
|
430
|
+
const pointer = this.items.get(key)
|
|
431
|
+
|
|
432
|
+
if (typeof pointer === 'undefined') {
|
|
433
|
+
return
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const dead = this.V[pointer]
|
|
437
|
+
this.items.delete(key)
|
|
438
|
+
|
|
439
|
+
if (this.count === 1) {
|
|
440
|
+
this.count = 0
|
|
441
|
+
this.head = 0
|
|
442
|
+
this.tail = 0
|
|
443
|
+
this.deletedSize = 0
|
|
444
|
+
return dead
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
const previous = this.backward[pointer]
|
|
448
|
+
const next = this.forward[pointer]
|
|
449
|
+
|
|
450
|
+
if (this.head === pointer) {
|
|
451
|
+
this.head = next
|
|
452
|
+
}
|
|
453
|
+
if (this.tail === pointer) {
|
|
454
|
+
this.tail = previous
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
this.forward[previous] = next
|
|
458
|
+
this.backward[next] = previous
|
|
459
|
+
|
|
460
|
+
this.count--
|
|
461
|
+
this.deleted[this.deletedSize++] = pointer
|
|
462
|
+
|
|
463
|
+
return dead
|
|
464
|
+
}
|
|
465
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Mapping } from './abc.js';
|
|
2
|
+
/**
|
|
3
|
+
* A `SortedMap` is a map that holds key value pairs in sorted orders of keys. Any primitive value (and objects that implement a `compare` or `lt` methods) can be used as keys or values.
|
|
4
|
+
* @see {@link Operators.compare}
|
|
5
|
+
* @see {@link Operators.lt}
|
|
6
|
+
* @template K, V
|
|
7
|
+
*/
|
|
8
|
+
export declare class SortedMap<K, V> extends Mapping<K, V> {
|
|
9
|
+
private readonly store;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new `SortedMap` object.
|
|
12
|
+
* @param {Iterable<[K, V]>} [iterable] Initialize the map with entries.
|
|
13
|
+
* @param {Comparer} [compareFn] The `compare` function to sort keys.
|
|
14
|
+
*/
|
|
15
|
+
constructor(iterable?: Iterable<[K, V]>, compareFn?: any);
|
|
16
|
+
/**
|
|
17
|
+
* Adds a new `key` with a `null` value, if the `key` doesn't exist.
|
|
18
|
+
* @param {K} key
|
|
19
|
+
* @returns {this} Returns the Map object.
|
|
20
|
+
*/
|
|
21
|
+
add(key: K): this;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the value associated with the `key` or `undefined`.
|
|
24
|
+
* @param {K} key
|
|
25
|
+
* @returns {?V} The key value or `undefined`.
|
|
26
|
+
*/
|
|
27
|
+
get(key: K): any;
|
|
28
|
+
/**
|
|
29
|
+
* Sets the value for the given `key`.
|
|
30
|
+
* @param {K} key
|
|
31
|
+
* @param {V} value
|
|
32
|
+
* @returns {this} Returns the Map object.
|
|
33
|
+
*/
|
|
34
|
+
set(key: K, value: V): void;
|
|
35
|
+
/**
|
|
36
|
+
* Returns the smallest key in the tree.
|
|
37
|
+
* @returns {?K}
|
|
38
|
+
*/
|
|
39
|
+
min(): K | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Returns the largest key in the tree.
|
|
42
|
+
* @returns {?K}
|
|
43
|
+
*/
|
|
44
|
+
max(): K | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Returns `true` if the `key` existed in the map and was removed.
|
|
47
|
+
* @param {K} key
|
|
48
|
+
* @returns {boolean} `true` if key was removed, otherwise `false`.
|
|
49
|
+
*/
|
|
50
|
+
delete(item: K): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Removes all key/value pairs in the tree.
|
|
53
|
+
*/
|
|
54
|
+
clear(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Returns the total key/value pairs in the tree.
|
|
57
|
+
* @returns {number}
|
|
58
|
+
*/
|
|
59
|
+
get size(): number;
|
|
60
|
+
/**
|
|
61
|
+
* Check if there are no key/value pairs in the tree.
|
|
62
|
+
* @returns {boolean} `true` if is empty.
|
|
63
|
+
*/
|
|
64
|
+
empty(): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Returns `true` if the `key` exists in the map.
|
|
67
|
+
* @param {K} key
|
|
68
|
+
* @returns {boolean} `true` if key is found, otherwise `false`.
|
|
69
|
+
*/
|
|
70
|
+
contains(key: K): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Returns `true` if the `key` exists in the map.
|
|
73
|
+
* @param {K} key
|
|
74
|
+
* @returns {boolean} `true` if key is found, otherwise `false`.
|
|
75
|
+
*/
|
|
76
|
+
has(key: K): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Returns a new iterator of all **ordered** keys in the map.
|
|
79
|
+
* @returns {Iterable<K>}
|
|
80
|
+
*/
|
|
81
|
+
keys(): Iterable<K>;
|
|
82
|
+
/**
|
|
83
|
+
* Returns a new iterator of all values **ordered** by their keys.
|
|
84
|
+
* @returns {Iterable<V>}
|
|
85
|
+
*/
|
|
86
|
+
values(): Iterable<V>;
|
|
87
|
+
/**
|
|
88
|
+
* Returns a new iterator of all key value pairs **ordered** by their keys.
|
|
89
|
+
* @returns {Iterable<[K, V]>}
|
|
90
|
+
*/
|
|
91
|
+
entries(): Iterable<[K, V]>;
|
|
92
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Mapping } from './abc.js';
|
|
2
|
+
import { SplayTree } from './SplayTree.js';
|
|
3
|
+
/**
|
|
4
|
+
* A `SortedMap` is a map that holds key value pairs in sorted orders of keys. Any primitive value (and objects that implement a `compare` or `lt` methods) can be used as keys or values.
|
|
5
|
+
* @see {@link Operators.compare}
|
|
6
|
+
* @see {@link Operators.lt}
|
|
7
|
+
* @template K, V
|
|
8
|
+
*/
|
|
9
|
+
export class SortedMap extends Mapping {
|
|
10
|
+
store;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new `SortedMap` object.
|
|
13
|
+
* @param {Iterable<[K, V]>} [iterable] Initialize the map with entries.
|
|
14
|
+
* @param {Comparer} [compareFn] The `compare` function to sort keys.
|
|
15
|
+
*/
|
|
16
|
+
constructor(iterable, compareFn) {
|
|
17
|
+
super();
|
|
18
|
+
this.store = new SplayTree(compareFn);
|
|
19
|
+
if (iterable) {
|
|
20
|
+
for (const pair of iterable) {
|
|
21
|
+
this.store.set(pair[0], pair[1] ?? null);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Adds a new `key` with a `null` value, if the `key` doesn't exist.
|
|
27
|
+
* @param {K} key
|
|
28
|
+
* @returns {this} Returns the Map object.
|
|
29
|
+
*/
|
|
30
|
+
add(key) {
|
|
31
|
+
this.store.set(key, null);
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Returns the value associated with the `key` or `undefined`.
|
|
36
|
+
* @param {K} key
|
|
37
|
+
* @returns {?V} The key value or `undefined`.
|
|
38
|
+
*/
|
|
39
|
+
get(key) {
|
|
40
|
+
return this.store.get(key);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Sets the value for the given `key`.
|
|
44
|
+
* @param {K} key
|
|
45
|
+
* @param {V} value
|
|
46
|
+
* @returns {this} Returns the Map object.
|
|
47
|
+
*/
|
|
48
|
+
set(key, value) {
|
|
49
|
+
return this.store.set(key, value);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns the smallest key in the tree.
|
|
53
|
+
* @returns {?K}
|
|
54
|
+
*/
|
|
55
|
+
min() {
|
|
56
|
+
return this.store.min();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Returns the largest key in the tree.
|
|
60
|
+
* @returns {?K}
|
|
61
|
+
*/
|
|
62
|
+
max() {
|
|
63
|
+
return this.store.max();
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns `true` if the `key` existed in the map and was removed.
|
|
67
|
+
* @param {K} key
|
|
68
|
+
* @returns {boolean} `true` if key was removed, otherwise `false`.
|
|
69
|
+
*/
|
|
70
|
+
delete(item) {
|
|
71
|
+
return this.store.remove(item) !== undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Removes all key/value pairs in the tree.
|
|
75
|
+
*/
|
|
76
|
+
clear() {
|
|
77
|
+
return this.store.clear();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns the total key/value pairs in the tree.
|
|
81
|
+
* @returns {number}
|
|
82
|
+
*/
|
|
83
|
+
get size() {
|
|
84
|
+
return this.store.size;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if there are no key/value pairs in the tree.
|
|
88
|
+
* @returns {boolean} `true` if is empty.
|
|
89
|
+
*/
|
|
90
|
+
empty() {
|
|
91
|
+
return this.store.empty();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns `true` if the `key` exists in the map.
|
|
95
|
+
* @param {K} key
|
|
96
|
+
* @returns {boolean} `true` if key is found, otherwise `false`.
|
|
97
|
+
*/
|
|
98
|
+
contains(key) {
|
|
99
|
+
return this.store.contains(key);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns `true` if the `key` exists in the map.
|
|
103
|
+
* @param {K} key
|
|
104
|
+
* @returns {boolean} `true` if key is found, otherwise `false`.
|
|
105
|
+
*/
|
|
106
|
+
has(key) {
|
|
107
|
+
return this.store.contains(key);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Returns a new iterator of all **ordered** keys in the map.
|
|
111
|
+
* @returns {Iterable<K>}
|
|
112
|
+
*/
|
|
113
|
+
keys() {
|
|
114
|
+
return this.store.keys();
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Returns a new iterator of all values **ordered** by their keys.
|
|
118
|
+
* @returns {Iterable<V>}
|
|
119
|
+
*/
|
|
120
|
+
values() {
|
|
121
|
+
return this.store.values();
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Returns a new iterator of all key value pairs **ordered** by their keys.
|
|
125
|
+
* @returns {Iterable<[K, V]>}
|
|
126
|
+
*/
|
|
127
|
+
entries() {
|
|
128
|
+
return this.store.entries();
|
|
129
|
+
}
|
|
130
|
+
}
|